arm_compute v17.09

Change-Id: I4bf8f4e6e5f84ce0d5b6f5ba570d276879f42a81
diff --git a/tests/validation/CL/ActivationLayer.cpp b/tests/validation/CL/ActivationLayer.cpp
new file mode 100644
index 0000000..83bd2d0
--- /dev/null
+++ b/tests/validation/CL/ActivationLayer.cpp
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLActivationLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ActivationFunctionsDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ActivationLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Define tolerance of the activation layer.
+ *
+ * @param[in] activation The activation function used.
+ * @param[in] data_type  Data type.
+ *
+ * @return Tolerance depending on the activation function.
+ */
+AbsoluteTolerance<float> tolerance(ActivationLayerInfo::ActivationFunction activation, DataType data_type)
+{
+    constexpr float epsilon = 1e-6f;
+
+    switch(activation)
+    {
+        case ActivationLayerInfo::ActivationFunction::LINEAR:
+            return AbsoluteTolerance<float>(data_type == DataType::F16 ? 0.2f : epsilon);
+        case ActivationLayerInfo::ActivationFunction::SQUARE:
+            return AbsoluteTolerance<float>(data_type == DataType::F16 ? 0.1f : epsilon);
+        case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+            if(is_data_type_fixed_point(data_type))
+            {
+                return AbsoluteTolerance<float>(5.f);
+            }
+            else
+            {
+                return AbsoluteTolerance<float>(data_type == DataType::F16 ? 0.001f : epsilon);
+            }
+        case ActivationLayerInfo::ActivationFunction::LEAKY_RELU:
+            return AbsoluteTolerance<float>(data_type == DataType::F16 ? 0.00001f : epsilon);
+        case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+        case ActivationLayerInfo::ActivationFunction::SQRT:
+            if(is_data_type_fixed_point(data_type))
+            {
+                return AbsoluteTolerance<float>(5.f);
+            }
+            else
+            {
+                return AbsoluteTolerance<float>(data_type == DataType::F16 ? 0.01f : 0.00001f);
+            }
+        case ActivationLayerInfo::ActivationFunction::TANH:
+            if(is_data_type_fixed_point(data_type))
+            {
+                return AbsoluteTolerance<float>(5.f);
+            }
+            else
+            {
+                return AbsoluteTolerance<float>(data_type == DataType::F16 ? 0.001f : 0.00001f);
+            }
+        default:
+            return AbsoluteTolerance<float>(epsilon);
+    }
+}
+
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
+{
+    DataType::F16,
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
+
+/** Input data sets. */
+const auto ActivationDataset = combine(combine(framework::dataset::make("InPlace", { false, true }), datasets::ActivationFunctions()), framework::dataset::make("AlphaBeta", { 0.5f, 1.f }));
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(ActivationLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), CNNDataTypes), framework::dataset::make("InPlace", { false, true })),
+               shape, data_type, in_place)
+{
+    // Set fixed point position data type allowed
+    const int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type, 1, fixed_point_position);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLActivationLayer act_layer;
+
+    if(in_place)
+    {
+        act_layer.configure(&src, nullptr, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::ABS));
+    }
+    else
+    {
+        act_layer.configure(&src, &dst, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::ABS));
+    }
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+
+    if(!in_place)
+    {
+        validate(dst.info()->valid_region(), valid_region);
+    }
+
+    // Validate padding
+    const int         step    = 16 / arm_compute::data_size_from_type(data_type);
+    const PaddingSize padding = PaddingCalculator(shape.x(), step).required_padding();
+    validate(src.info()->padding(), padding);
+
+    if(!in_place)
+    {
+        validate(dst.info()->padding(), padding);
+    }
+}
+
+template <typename T>
+using CLActivationLayerFixture = ActivationValidationFixture<CLTensor, CLAccessor, CLActivationLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLActivationLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ActivationDataset),
+                                                                                                            framework::dataset::make("DataType",
+                                                                                                                    DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLActivationLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ActivationDataset),
+                                                                                                          framework::dataset::make("DataType",
+                                                                                                                  DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLActivationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ActivationDataset), framework::dataset::make("DataType",
+                                                                                                             DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLActivationLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ActivationDataset), framework::dataset::make("DataType",
+                                                                                                           DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLActivationLayerFixedPointFixture = ActivationValidationFixedPointFixture<CLTensor, CLAccessor, CLActivationLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// We test for fixed point precision [3,5] because [1,2] and [6,7] ranges cause
+// overflowing issues in most of the transcendentals functions.
+FIXTURE_DATA_TEST_CASE(RunSmall, CLActivationLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ActivationDataset),
+                                                                                                                        framework::dataset::make("DataType",
+                                                                                                                                DataType::QS8)),
+                                                                                                                        framework::dataset::make("FractionalBits", 3, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLActivationLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ActivationDataset),
+                                                                                                                      framework::dataset::make("DataType",
+                                                                                                                              DataType::QS8)),
+                                                                                                                      framework::dataset::make("FractionalBits", 3, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 14
+FIXTURE_DATA_TEST_CASE(RunSmall, CLActivationLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ActivationDataset),
+                       framework::dataset::make("DataType",
+                                                DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLActivationLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ActivationDataset),
+                                                                                                                       framework::dataset::make("DataType",
+                                                                                                                               DataType::QS16)),
+                                                                                                                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance(_function, _data_type));
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/ArithmeticAddition.cpp b/tests/validation/CL/ArithmeticAddition.cpp
new file mode 100644
index 0000000..51257b4
--- /dev/null
+++ b/tests/validation/CL/ArithmeticAddition.cpp
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLArithmeticAddition.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ConvertPolicyDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ArithmeticAdditionFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Input data sets **/
+const auto ArithmeticAdditionU8Dataset = combine(combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::U8)), framework::dataset::make("DataType",
+                                                 DataType::U8));
+const auto ArithmeticAdditionS16Dataset = combine(combine(framework::dataset::make("DataType", { DataType::U8, DataType::S16 }), framework::dataset::make("DataType", DataType::S16)),
+                                                  framework::dataset::make("DataType", DataType::S16));
+const auto ArithmeticAdditionQS8Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS8), framework::dataset::make("DataType", DataType::QS8)),
+                                                  framework::dataset::make("DataType", DataType::QS8));
+const auto ArithmeticAdditionQS16Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS16), framework::dataset::make("DataType", DataType::QS16)),
+                                                   framework::dataset::make("DataType", DataType::QS16));
+const auto ArithmeticAdditionFP16Dataset = combine(combine(framework::dataset::make("DataType", DataType::F16), framework::dataset::make("DataType", DataType::F16)),
+                                                   framework::dataset::make("DataType", DataType::F16));
+const auto ArithmeticAdditionFP32Dataset = combine(combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::F32)),
+                                                   framework::dataset::make("DataType", DataType::F32));
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(ArithmeticAddition)
+
+template <typename T>
+using CLArithmeticAdditionFixture = ArithmeticAdditionValidationFixture<CLTensor, CLAccessor, CLArithmeticAddition, T>;
+
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
+{
+    // Create tensors
+    CLTensor ref_src1 = create_tensor<CLTensor>(shape, DataType::U8);
+    CLTensor ref_src2 = create_tensor<CLTensor>(shape, DataType::U8);
+    CLTensor dst      = create_tensor<CLTensor>(shape, DataType::U8);
+
+    // Create and Configure function
+    CLArithmeticAddition add;
+    add.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticAdditionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionU8Dataset),
+                                                                                                                  framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
+                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, data_type, policy)
+{
+    // Create tensors
+    CLTensor ref_src1 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor ref_src2 = create_tensor<CLTensor>(shape, DataType::S16);
+    CLTensor dst      = create_tensor<CLTensor>(shape, DataType::S16);
+
+    // Create and Configure function
+    CLArithmeticAddition add;
+    add.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticAdditionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionS16Dataset),
+                                                                                                                  framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticAdditionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticAdditionS16Dataset),
+                                                                                                                framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+template <typename T>
+using CLArithmeticAdditionFixedPointFixture = ArithmeticAdditionValidationFixedPointFixture<CLTensor, CLAccessor, CLArithmeticAddition, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticAdditionFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ArithmeticAdditionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticAdditionFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticAdditionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticAdditionFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ArithmeticAdditionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticAdditionFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticAdditionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticAdditionFixture<half>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), ArithmeticAdditionFP16Dataset),
+                                                                                                         framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
+{
+    // Create tensors
+    CLTensor ref_src1 = create_tensor<CLTensor>(shape, DataType::F32);
+    CLTensor ref_src2 = create_tensor<CLTensor>(shape, DataType::F32);
+    CLTensor dst      = create_tensor<CLTensor>(shape, DataType::F32);
+
+    // Create and Configure function
+    CLArithmeticAddition add;
+    add.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticAdditionFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionFP32Dataset),
+                                                                                                                framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticAdditionFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticAdditionFP32Dataset),
+                                                                                                              framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/ArithmeticSubtraction.cpp b/tests/validation/CL/ArithmeticSubtraction.cpp
new file mode 100644
index 0000000..817a31f
--- /dev/null
+++ b/tests/validation/CL/ArithmeticSubtraction.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2017 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 CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLArithmeticSubtraction.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ConvertPolicyDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ArithmeticSubtractionFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Input data sets **/
+const auto ArithmeticSubtractionU8Dataset = combine(combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::U8)),
+                                                    framework::dataset::make("DataType",
+                                                                             DataType::U8));
+const auto ArithmeticSubtractionS16Dataset = combine(combine(framework::dataset::make("DataType", { DataType::U8, DataType::S16 }), framework::dataset::make("DataType", DataType::S16)),
+                                                     framework::dataset::make("DataType", DataType::S16));
+const auto ArithmeticSubtractionQS8Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS8), framework::dataset::make("DataType", DataType::QS8)),
+                                                     framework::dataset::make("DataType", DataType::QS8));
+const auto ArithmeticSubtractionQS16Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS16), framework::dataset::make("DataType", DataType::QS16)),
+                                                      framework::dataset::make("DataType", DataType::QS16));
+const auto ArithmeticSubtractionFP16Dataset = combine(combine(framework::dataset::make("DataType", DataType::F16), framework::dataset::make("DataType", DataType::F16)),
+                                                      framework::dataset::make("DataType", DataType::F16));
+const auto ArithmeticSubtractionFP32Dataset = combine(combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::F32)),
+                                                      framework::dataset::make("DataType", DataType::F32));
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(ArithmeticSubtraction)
+
+template <typename T>
+using CLArithmeticSubtractionFixture = ArithmeticSubtractionValidationFixture<CLTensor, CLAccessor, CLArithmeticSubtraction, T>;
+
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
+{
+    // Create tensors
+    CLTensor ref_src1 = create_tensor<CLTensor>(shape, DataType::U8);
+    CLTensor ref_src2 = create_tensor<CLTensor>(shape, DataType::U8);
+    CLTensor dst      = create_tensor<CLTensor>(shape, DataType::U8);
+
+    // Create and Configure function
+    CLArithmeticSubtraction sub;
+    sub.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticSubtractionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionU8Dataset),
+                                                                                                                     framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
+                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, data_type, policy)
+{
+    // Create tensors
+    CLTensor ref_src1 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor ref_src2 = create_tensor<CLTensor>(shape, DataType::S16);
+    CLTensor dst      = create_tensor<CLTensor>(shape, DataType::S16);
+
+    // Create and Configure function
+    CLArithmeticSubtraction sub;
+    sub.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticSubtractionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionS16Dataset),
+                                                                                                                     framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticSubtractionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticSubtractionS16Dataset),
+                                                                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+template <typename T>
+using CLArithmeticSubtractionFixedPointFixture = ArithmeticSubtractionValidationFixedPointFixture<CLTensor, CLAccessor, CLArithmeticSubtraction, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticSubtractionFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ArithmeticSubtractionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticSubtractionFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticSubtractionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticSubtractionFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(),
+                       ArithmeticSubtractionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticSubtractionFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticSubtractionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticSubtractionFixture<half>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionFP16Dataset),
+                                                                                                            framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
+{
+    // Create tensors
+    CLTensor ref_src1 = create_tensor<CLTensor>(shape, DataType::F32);
+    CLTensor ref_src2 = create_tensor<CLTensor>(shape, DataType::F32);
+    CLTensor dst      = create_tensor<CLTensor>(shape, DataType::F32);
+
+    // Create and Configure function
+    CLArithmeticSubtraction sub;
+    sub.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLArithmeticSubtractionFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionFP32Dataset),
+                                                                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLArithmeticSubtractionFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticSubtractionFP32Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/BatchNormalizationLayer.cpp b/tests/validation/CL/BatchNormalizationLayer.cpp
new file mode 100644
index 0000000..ac30c63
--- /dev/null
+++ b/tests/validation/CL/BatchNormalizationLayer.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLBatchNormalizationLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/RandomBatchNormalizationLayerDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BatchNormalizationLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr AbsoluteTolerance<float> tolerance_f(0.00001f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
+constexpr AbsoluteTolerance<float> tolerance_qs8(3.0f);   /**< Tolerance value for comparing reference's output against implementation's output for DataType::QS8 */
+constexpr AbsoluteTolerance<float> tolerance_qs16(6.0f);  /**< Tolerance value for comparing reference's output against implementation's output for DataType::QS16 */
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(BatchNormalizationLayer)
+
+template <typename T>
+using CLBatchNormalizationLayerFixture = BatchNormalizationLayerValidationFixture<CLTensor, CLAccessor, CLBatchNormalizationLayer, T>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(datasets::RandomBatchNormalizationLayerDataset(), framework::dataset::make("DataType", { DataType::QS8, DataType::QS16, DataType::F32 })),
+               shape0, shape1, epsilon, dt)
+{
+    // Set fixed point position data type allowed
+    int fixed_point_position = (arm_compute::is_data_type_fixed_point(dt)) ? 3 : 0;
+
+    // Create tensors
+    CLTensor src   = create_tensor<CLTensor>(shape0, dt, 1, fixed_point_position);
+    CLTensor dst   = create_tensor<CLTensor>(shape0, dt, 1, fixed_point_position);
+    CLTensor mean  = create_tensor<CLTensor>(shape1, dt, 1, fixed_point_position);
+    CLTensor var   = create_tensor<CLTensor>(shape1, dt, 1, fixed_point_position);
+    CLTensor beta  = create_tensor<CLTensor>(shape1, dt, 1, fixed_point_position);
+    CLTensor gamma = create_tensor<CLTensor>(shape1, dt, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLBatchNormalizationLayer norm;
+    norm.configure(&src, &dst, &mean, &var, &beta, &gamma, epsilon);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape0);
+    validate(dst.info()->valid_region(), valid_region);
+}
+
+TEST_SUITE(Float)
+FIXTURE_DATA_TEST_CASE(Random, CLBatchNormalizationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::RandomBatchNormalizationLayerDataset(),
+                                                                                                                   framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f, 0);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(Quantized)
+template <typename T>
+using CLBatchNormalizationLayerFixedPointFixture = BatchNormalizationLayerValidationFixedPointFixture<CLTensor, CLAccessor, CLBatchNormalizationLayer, T>;
+
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(Random, CLBatchNormalizationLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::RandomBatchNormalizationLayerDataset(),
+                       framework::dataset::make("DataType", DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs8, 0);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(Random, CLBatchNormalizationLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::RandomBatchNormalizationLayerDataset(),
+                       framework::dataset::make("DataType", DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs16, 0);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/BitwiseAnd.cpp b/tests/validation/CL/BitwiseAnd.cpp
index 4cd64a2..3e458a4 100644
--- a/tests/validation/CL/BitwiseAnd.cpp
+++ b/tests/validation/CL/BitwiseAnd.cpp
@@ -21,142 +21,42 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "CL/CLAccessor.h"
-#include "CL/Helper.h"
-#include "Globals.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/CL/CLSubTensor.h"
-#include "arm_compute/runtime/CL/CLTensor.h"
-#include "arm_compute/runtime/CL/CLTensorAllocator.h"
 #include "arm_compute/runtime/CL/functions/CLBitwiseAnd.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseAndFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::cl;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Neon bitwise and function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-CLTensor compute_bitwise_and(const TensorShape &shape)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(BitwiseAnd)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
 {
     // Create tensors
-    CLTensor src1 = create_tensor(shape, DataType::U8);
-    CLTensor src2 = create_tensor(shape, DataType::U8);
-    CLTensor dst  = create_tensor(shape, DataType::U8);
+    CLTensor src1 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor src2 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst  = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
-    CLBitwiseAnd band;
-    band.configure(&src1, &src2, &dst);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(CLAccessor(src1), 0);
-    library->fill_tensor_uniform(CLAccessor(src2), 1);
-
-    // Compute function
-    band.run();
-
-    return dst;
-}
-
-/** Compute OpenCL bitwise and function that splits the input and output in two subtensor.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-CLTensor compute_bitwise_and_subtensor(const TensorShape &shape)
-{
-    // Create tensors
-    CLTensor src1 = create_tensor(shape, DataType::U8);
-    CLTensor src2 = create_tensor(shape, DataType::U8);
-    CLTensor dst  = create_tensor(shape, DataType::U8);
-
-    // Create SubTensors
-    int         coord_z   = shape.z() / 2;
-    TensorShape sub_shape = shape;
-    sub_shape.set(2, coord_z);
-
-    CLSubTensor src1_sub1(&src1, sub_shape, Coordinates());
-    CLSubTensor src1_sub2(&src1, sub_shape, Coordinates(0, 0, coord_z));
-    CLSubTensor src2_sub1(&src2, sub_shape, Coordinates());
-    CLSubTensor src2_sub2(&src2, sub_shape, Coordinates(0, 0, coord_z));
-    CLSubTensor dst_sub1(&dst, sub_shape, Coordinates());
-    CLSubTensor dst_sub2(&dst, sub_shape, Coordinates(0, 0, coord_z));
-
-    // Create and configure function
-    CLBitwiseAnd band1, band2;
-    band1.configure(&src1_sub1, &src2_sub1, &dst_sub1);
-    band2.configure(&src1_sub2, &src2_sub2, &dst_sub2);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    std::uniform_int_distribution<> distribution(0, 255);
-    library->fill(CLAccessor(src1), distribution, 0);
-    library->fill(CLAccessor(src2), distribution, 1);
-
-    // Compute function
-    band1.run();
-    band2.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(CL)
-BOOST_AUTO_TEST_SUITE(BitwiseAnd)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, SmallShapes() + LargeShapes(), shape)
-{
-    // Create tensors
-    CLTensor src1 = create_tensor(shape, DataType::U8);
-    CLTensor src2 = create_tensor(shape, DataType::U8);
-    CLTensor dst  = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    CLBitwiseAnd band;
-    band.configure(&src1, &src2, &dst);
+    CLBitwiseAnd bitwise_and;
+    bitwise_and.configure(&src1, &src2, &dst);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
@@ -165,54 +65,30 @@
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src1.info()->padding(), padding);
     validate(src2.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
+template <typename T>
+using CLBitwiseAndFixture = BitwiseAndValidationFixture<CLTensor, CLAccessor, CLBitwiseAnd, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLBitwiseAndFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
 {
-    // Compute function
-    CLTensor dst = compute_bitwise_and(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_and(shape);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLBitwiseAndFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_AUTO_TEST_CASE(RunSubTensor)
-{
-    // Create shape
-    TensorShape shape(27U, 35U, 8U, 2U);
-
-    // Compute function
-    CLTensor dst = compute_bitwise_and_subtensor(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_and(shape);
-
-    // Validate output
-    validate(CLAccessor(dst), ref_dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(), shape)
-{
-    // Compute function
-    CLTensor dst = compute_bitwise_and(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_and(shape);
-
-    // Validate output
-    validate(CLAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/BitwiseNot.cpp b/tests/validation/CL/BitwiseNot.cpp
new file mode 100644
index 0000000..376bde9
--- /dev/null
+++ b/tests/validation/CL/BitwiseNot.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/functions/CLBitwiseNot.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseNotFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(BitwiseNot)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLBitwiseNot bitwise_not;
+    bitwise_not.configure(&src, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+template <typename T>
+using CLBitwiseNotFixture = BitwiseNotValidationFixture<CLTensor, CLAccessor, CLBitwiseNot, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLBitwiseNotFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLBitwiseNotFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/BitwiseOr.cpp b/tests/validation/CL/BitwiseOr.cpp
new file mode 100644
index 0000000..ecff0be
--- /dev/null
+++ b/tests/validation/CL/BitwiseOr.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/functions/CLBitwiseOr.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseOrFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(BitwiseOr)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src1 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor src2 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst  = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLBitwiseOr bitwise_or;
+    bitwise_or.configure(&src1, &src2, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src1.info()->valid_region(), valid_region);
+    validate(src2.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src1.info()->padding(), padding);
+    validate(src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+template <typename T>
+using CLBitwiseOrFixture = BitwiseOrValidationFixture<CLTensor, CLAccessor, CLBitwiseOr, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLBitwiseOrFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                         DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLBitwiseOrFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                       DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/BitwiseXor.cpp b/tests/validation/CL/BitwiseXor.cpp
new file mode 100644
index 0000000..3104894
--- /dev/null
+++ b/tests/validation/CL/BitwiseXor.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/functions/CLBitwiseXor.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseXorFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(BitwiseXor)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src1 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor src2 = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst  = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLBitwiseXor bitwise_xor;
+    bitwise_xor.configure(&src1, &src2, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src1.info()->valid_region(), valid_region);
+    validate(src2.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src1.info()->padding(), padding);
+    validate(src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+template <typename T>
+using CLBitwiseXorFixture = BitwiseXorValidationFixture<CLTensor, CLAccessor, CLBitwiseXor, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLBitwiseXorFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLBitwiseXorFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/Box3x3.cpp b/tests/validation/CL/Box3x3.cpp
new file mode 100644
index 0000000..d5a4932
--- /dev/null
+++ b/tests/validation/CL/Box3x3.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/functions/CLBox3x3.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/Box3x3Fixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr unsigned int filter_size = 3;              /* Size of the kernel/filter in number of elements. */
+constexpr BorderSize   border_size(filter_size / 2); /* Border size of the kernel/filter around its central element. */
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(Box3x3)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+                                                                   datasets::BorderModes()),
+               shape, data_type, border_mode)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLBox3x3 box3x3;
+    box3x3.configure(&src, &dst, border_mode);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size);
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+    calculator.set_border_size(1);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-1);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst.info()->padding(), dst_padding);
+}
+
+template <typename T>
+using CLBox3x3Fixture = Box3x3ValidationFixture<CLTensor, CLAccessor, CLBox3x3, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLBox3x3Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                              DataType::U8)),
+                                                                                                      datasets::BorderModes()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLBox3x3Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::U8)),
+                                                                                                    datasets::BorderModes()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.cpp b/tests/validation/CL/CLFixture.cpp
deleted file mode 100644
index 845e166..0000000
--- a/tests/validation/CL/CLFixture.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "validation/CL/CLFixture.h"
-
-#include "boost_wrapper.h"
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::validation;
-using namespace arm_compute::test::validation::cl;
-
-BOOST_GLOBAL_FIXTURE(CLFixture);
diff --git a/tests/validation/CL/ConvolutionLayer.cpp b/tests/validation/CL/ConvolutionLayer.cpp
new file mode 100644
index 0000000..9f9295c
--- /dev/null
+++ b/tests/validation/CL/ConvolutionLayer.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2017 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 CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLConvolutionLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/LargeConvolutionLayerDataset.h"
+#include "tests/datasets/SmallConvolutionLayerDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ConvolutionLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+RelativeTolerance<float>            tolerance_f32(0.05f);                 /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
+RelativeTolerance<half_float::half> tolerance_f16(half_float::half(0.2)); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F16 */
+constexpr AbsoluteTolerance<float>  tolerance_q(1.0f);                    /**< Tolerance value for comparing reference's output against implementation's output for fixed point data types */
+constexpr float                     tolerance_num = 0.07f;                /**< Tolerance number */
+
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
+{
+    DataType::F16,
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(ConvolutionLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallConvolutionLayerDataset(), datasets::LargeConvolutionLayerDataset()), CNNDataTypes),
+               input_shape, weights_shape, bias_shape, output_shape, info, data_type)
+{
+    // Set fixed point position data type allowed
+    int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
+
+    // Create tensors
+    CLTensor src     = create_tensor<CLTensor>(input_shape, data_type, 1, fixed_point_position);
+    CLTensor weights = create_tensor<CLTensor>(weights_shape, data_type, 1, fixed_point_position);
+    CLTensor bias    = create_tensor<CLTensor>(bias_shape, data_type, 1, fixed_point_position);
+    CLTensor dst     = create_tensor<CLTensor>(output_shape, data_type, 1, fixed_point_position);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLConvolutionLayer conv;
+    conv.configure(&src, &weights, &bias, &dst, info);
+
+    // Validate valid region
+    const ValidRegion src_valid_region     = shape_to_valid_region(input_shape);
+    const ValidRegion weights_valid_region = shape_to_valid_region(weights_shape);
+    const ValidRegion bias_valid_region    = shape_to_valid_region(bias_shape);
+    const ValidRegion dst_valid_region     = shape_to_valid_region(output_shape);
+
+    validate(src.info()->valid_region(), src_valid_region);
+    validate(weights.info()->valid_region(), weights_valid_region);
+    validate(bias.info()->valid_region(), bias_valid_region);
+    validate(dst.info()->valid_region(), dst_valid_region);
+}
+
+template <typename T>
+using CLConvolutionLayerFixture = ConvolutionValidationFixture<CLTensor, CLAccessor, CLConvolutionLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallConvolutionLayerDataset(),
+                                                                                                                     framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                             framework::dataset::make("DataType",
+                                                                                                                     DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                   framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                           framework::dataset::make("DataType",
+                                                                                                                   DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallConvolutionLayerDataset(),
+                                                                                                                      framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                              framework::dataset::make("DataType",
+                                                                                                                      DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                    framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                            framework::dataset::make("DataType",
+                                                                                                                    DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLConvolutionLayerFixedPointFixture = ConvolutionValidationFixedPointFixture<CLTensor, CLAccessor, CLConvolutionLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// We test for fixed point precision [4,6]
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallConvolutionLayerDataset(),
+                       framework::dataset::make("ReshapeWeights", { true, false })),
+                       framework::dataset::make("DataType",
+                                                DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 4, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                       framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                                       framework::dataset::make("DataType",
+                                                                                                                               DataType::QS8)),
+                                                                                                                       framework::dataset::make("FractionalBits", 4, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallConvolutionLayerDataset(),
+                       framework::dataset::make("ReshapeWeights", { true, false })),
+                       framework::dataset::make("DataType",
+                                                DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                        framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                                        framework::dataset::make("DataType",
+                                                                                                                                DataType::QS16)),
+                                                                                                                        framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/DepthConcatenateLayer.cpp b/tests/validation/CL/DepthConcatenateLayer.cpp
new file mode 100644
index 0000000..a7adde1
--- /dev/null
+++ b/tests/validation/CL/DepthConcatenateLayer.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLDepthConcatenate.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DepthConcatenateLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(DepthConcatenateLayer)
+
+template <typename T>
+using CLDepthConcatenateLayerFixture = DepthConcatenateValidationFixture<CLTensor, ICLTensor, CLAccessor, CLDepthConcatenate, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConcatenateLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                                  DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConcatenateLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                                DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConcatenateLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConcatenateLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::DepthConcatenateShapes(), framework::dataset::make("DataType",
+                                                                                                                 DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConcatenateLayerFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(),
+                                                                                                                    framework::dataset::make("DataType",
+                                                                                                                            DataType::QS8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConcatenateLayerFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::DepthConcatenateShapes(),
+                                                                                                                  framework::dataset::make("DataType",
+                                                                                                                          DataType::QS8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConcatenateLayerFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(),
+                                                                                                                     framework::dataset::make("DataType",
+                                                                                                                             DataType::QS16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConcatenateLayerFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(datasets::DepthConcatenateShapes(),
+                                                                                                                   framework::dataset::make("DataType",
+                                                                                                                           DataType::QS16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/DepthConvert.cpp b/tests/validation/CL/DepthConvert.cpp
index 7a421ec..57669f0 100644
--- a/tests/validation/CL/DepthConvert.cpp
+++ b/tests/validation/CL/DepthConvert.cpp
@@ -18,396 +18,467 @@
  * 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
+ * OUT OF OR IN CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "CL/CLAccessor.h"
-#include "CL/Helper.h"
-#include "Globals.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
 #include "arm_compute/runtime/CL/functions/CLDepthConvert.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ConvertPolicyDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DepthConvertFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::cl;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-/** Compute CL depth convert function.
- *
- * @param[in] shape  Shape of the input and output tensors.
- * @param[in] dt_in  Data type of input tensor.
- * @param[in] dt_out Data type of the output tensor.
- * @param[in] policy Conversion policy.
- * @param[in] shift  Value for down/up conversions. Must be 0 <= shift < 8.
- *
- * @return Computed output CLtensor.
- */
-CLTensor compute_depth_convert(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift)
+/** Input data sets **/
+const auto DepthConvertU8toU16Dataset             = combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::U16));
+const auto DepthConvertU8toS16Dataset             = combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::S16));
+const auto DepthConvertU8toS32Dataset             = combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::S32));
+const auto DepthConvertU16toU8Dataset             = combine(framework::dataset::make("DataType", DataType::U16), framework::dataset::make("DataType", DataType::U8));
+const auto DepthConvertU16toU32Dataset            = combine(framework::dataset::make("DataType", DataType::U16), framework::dataset::make("DataType", DataType::U32));
+const auto DepthConvertS16toU8Dataset             = combine(framework::dataset::make("DataType", DataType::S16), framework::dataset::make("DataType", DataType::U8));
+const auto DepthConvertS16toS32Dataset            = combine(framework::dataset::make("DataType", DataType::S16), framework::dataset::make("DataType", DataType::S32));
+const auto DepthConvertQS8toFP32Dataset           = combine(framework::dataset::make("DataType", DataType::QS8), framework::dataset::make("DataType", DataType::F32));
+const auto DepthConvertQS16toFP32Dataset          = combine(framework::dataset::make("DataType", DataType::QS16), framework::dataset::make("DataType", DataType::F32));
+const auto DepthConvertFP32toQS8Dataset           = combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::QS8));
+const auto DepthConvertFP32toQS16Dataset          = combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::QS16));
+const auto DepthConvertShiftDataset               = framework::dataset::make("Shift", 0, 7);
+const auto DepthConvertFixedPointQuantizedDataset = framework::dataset::make("FractionalBits", 1, 7);
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(DepthConvert)
+template <typename T>
+using CLDepthConvertToU16Fixture = DepthConvertValidationFixture<CLTensor, CLAccessor, CLDepthConvert, T, uint16_t>;
+template <typename T>
+using CLDepthConvertToS16Fixture = DepthConvertValidationFixture<CLTensor, CLAccessor, CLDepthConvert, T, int16_t>;
+template <typename T>
+using CLDepthConvertToS32Fixture = DepthConvertValidationFixture<CLTensor, CLAccessor, CLDepthConvert, T, int32_t>;
+template <typename T>
+using CLDepthConvertToU8Fixture = DepthConvertValidationFixture<CLTensor, CLAccessor, CLDepthConvert, T, uint8_t>;
+template <typename T>
+using CLDepthConvertToU32Fixture = DepthConvertValidationFixture<CLTensor, CLAccessor, CLDepthConvert, T, uint32_t>;
+template <typename T>
+using CLDepthConvertToFP32FixedPointFixture = DepthConvertValidationFractionalBitsFixture<CLTensor, CLAccessor, CLDepthConvert, T, float>;
+template <typename T>
+using CLDepthConvertToQS8FixedPointFixture = DepthConvertValidationFractionalBitsFixture<CLTensor, CLAccessor, CLDepthConvert, T, int8_t>;
+template <typename T>
+using CLDepthConvertToQS16FixedPointFixture = DepthConvertValidationFractionalBitsFixture<CLTensor, CLAccessor, CLDepthConvert, T, int16_t>;
+
+TEST_SUITE(U8_to_U16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
+    int fixed_point_position = 0;
+
     // Create tensors
-    CLTensor src = create_tensor(shape, dt_in);
-    CLTensor dst = create_tensor(shape, dt_out);
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::U8, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::U16, 1, fixed_point_position);
 
-    // Create and configure function
-    CLDepthConvert depth_convert;
-    depth_convert.configure(&src, &dst, policy, shift);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(CLAccessor(src), 0);
-
-    // Compute function
-    depth_convert.run();
-
-    return dst;
-}
-/** Configure and validate region/padding function.
- *
- * @param[in] shape  Shape of the input and output tensors.
- * @param[in] dt_in  Data type of input tensor.
- * @param[in] dt_out Data type of the output tensor.
- * @param[in] policy Conversion policy.
- * @param[in] shift  Value for down/up conversions. Must be 0 <= shift < 8.
- *
- */
-void compute_configure_validate(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift)
-{
-    // Create tensors
-    CLTensor src = create_tensor(shape, dt_in);
-    CLTensor dst = create_tensor(shape, dt_out);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
+    // Create and Configure function
     CLDepthConvert depth_convert;
     depth_convert.configure(&src, &dst, policy, shift);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src.info()->valid_region(), valid_region);
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
-} // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(CL)
-BOOST_AUTO_TEST_SUITE(DepthConvert)
-
-BOOST_AUTO_TEST_SUITE(U8_to_U16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConvertToU16Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU8toU16Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U8, DataType::U16, policy, shift);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
-{
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U8, DataType::U16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::U16, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConvertToU16Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU8toU16Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U8, DataType::U16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::U16, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U8_to_S16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(U8_to_S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U8, DataType::S16, policy, shift);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::U8, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::S16, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConvertToS16Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU8toS16Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U8, DataType::S16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S16, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConvertToS16Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU8toS16Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U8, DataType::S16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S16, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(U8_to_S32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE_END()
+TEST_SUITE(U8_to_S32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U8, DataType::S32, policy, shift);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::U8, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::S32, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConvertToS32Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU8toS32Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U8, DataType::S32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConvertToS32Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU8toS32Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U8, DataType::S32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U16_to_U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(U16_to_U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U16, DataType::U8, policy, shift);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::U16, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::U8, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConvertToU8Fixture<uint16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU16toU8Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U16, DataType::U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConvertToU8Fixture<uint16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU16toU8Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U16, DataType::U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U16_to_U32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(U16_to_U32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U16, DataType::U32, policy, shift);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::U16, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::U32, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConvertToU32Fixture<uint16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU16toU32Dataset),
+                                                                                                                  framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                  DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U16, DataType::U32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U32, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConvertToU32Fixture<uint16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU16toU32Dataset),
+                                                                                                                        framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::U16, DataType::U32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U32, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(S16_to_U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(S16_to_U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::S16, DataType::U8, policy, shift);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::S16, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::U8, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConvertToU8Fixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertS16toU8Dataset),
+                                                                                                                        framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::S16, DataType::U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConvertToU8Fixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertS16toU8Dataset),
+                                                                                                                      framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                              DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::S16, DataType::U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(S16_to_S32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(S16_to_S32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::S16, DataType::S32, policy, shift);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::S16, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::S32, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthConvertToS32Fixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertS16toS32Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::S16, DataType::S32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthConvertToS32Fixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertS16toS32Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    CLTensor dst = compute_depth_convert(shape, DataType::S16, DataType::S32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE(Quantized_to_FP32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::QS8, DataType::QS16 })),
+                                                                           framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertFixedPointQuantizedDataset),
+               shape, dt, policy, fixed_point_position)
+{
+    int shift = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, dt, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::F32, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallQS8, CLDepthConvertToFP32FixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertQS8toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallQS16, CLDepthConvertToFP32FixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertQS16toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeQS8, CLDepthConvertToFP32FixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertQS8toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeQS16, CLDepthConvertToFP32FixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertQS16toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32_to_Quantized)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::QS8, DataType::QS16 })),
+                                                                           framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertFixedPointQuantizedDataset),
+               shape, dt, policy, fixed_point_position)
+{
+    int shift = 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::F32, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, dt, 1, fixed_point_position);
+
+    // Create and Configure function
+    CLDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallQS8, CLDepthConvertToQS8FixedPointFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertFP32toQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallQS16, CLDepthConvertToQS16FixedPointFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertFP32toQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeQS8, CLDepthConvertToQS8FixedPointFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertFP32toQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeQS16, CLDepthConvertToQS16FixedPointFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertFP32toQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/DepthwiseConvolution.cpp b/tests/validation/CL/DepthwiseConvolution.cpp
new file mode 100644
index 0000000..5f1bde8
--- /dev/null
+++ b/tests/validation/CL/DepthwiseConvolution.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017 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 CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLDepthwiseConvolution.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/DepthwiseConvolutionDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DepthwiseConvolutionFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr RelativeTolerance<float> tolerance_f32(0.01f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(DepthwiseConvolutionLayer)
+
+template <typename T>
+using CLDepthwiseConvolutionFixture = DepthwiseConvolutionValidationFixture<CLTensor, CLAccessor, CLDepthwiseConvolution, T>;
+
+TEST_SUITE(Generic)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionFixture<float>, framework::DatasetMode::PRECOMMIT, datasets::SmallDepthwiseConvolutionDataset())
+{
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionFixture<float>, framework::DatasetMode::NIGHTLY, datasets::LargeDepthwiseConvolutionDataset())
+{
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+
+template <typename T>
+using CLDepthwiseConvolutionFixture3x3 = DepthwiseConvolutionValidationFixture<CLTensor, CLAccessor, CLDepthwiseConvolution3x3, T>;
+
+TEST_SUITE(W3x3)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseConvolutionFixture3x3<float>, framework::DatasetMode::PRECOMMIT, datasets::SmallDepthwiseConvolutionDataset3x3())
+{
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDepthwiseConvolutionFixture3x3<float>, framework::DatasetMode::NIGHTLY, datasets::LargeDepthwiseConvolutionDataset3x3())
+{
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/DepthwiseSeparableConvolutionLayer.cpp b/tests/validation/CL/DepthwiseSeparableConvolutionLayer.cpp
new file mode 100644
index 0000000..4d9f6b8
--- /dev/null
+++ b/tests/validation/CL/DepthwiseSeparableConvolutionLayer.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017 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 CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLDepthwiseSeparableConvolutionLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/MobileNetDepthwiseSeparableConvolutionLayerDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DepthwiseSeparableConvolutionLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+RelativeTolerance<float> tolerance_f32(0.1f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
+const float              tolerance_num = 0.001f;
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(DepthwiseSeparableConvolutionLayer)
+
+// Configuration test to do
+
+template <typename T>
+using CLDepthwiseSeparableConvolutionLayerFixture = DepthwiseSeparableConvolutionValidationFixture<CLTensor, CLAccessor, CLDepthwiseSeparableConvolutionLayer, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDepthwiseSeparableConvolutionLayerFixture<float>, framework::DatasetMode::PRECOMMIT, datasets::MobileNetDepthwiseSeparableConvolutionLayerDataset())
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/DequantizationLayer.cpp b/tests/validation/CL/DequantizationLayer.cpp
new file mode 100644
index 0000000..8e1ba60
--- /dev/null
+++ b/tests/validation/CL/DequantizationLayer.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLDequantizationLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DequantizationLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+const auto DequantizationShapes = concat(concat(concat(datasets::Small3DShapes(),
+                                                       datasets::Large3DShapes()),
+                                                datasets::Small4DShapes()),
+                                         datasets::Large4DShapes());
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(DequantizationLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(DequantizationShapes, framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    TensorShape shape_min_max = shape;
+    shape_min_max.set(Window::DimX, 2);
+
+    // Remove Y and Z dimensions and keep the batches
+    shape_min_max.remove_dimension(1);
+    shape_min_max.remove_dimension(1);
+
+    // Create tensors
+    CLTensor src     = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst     = create_tensor<CLTensor>(shape, DataType::F32);
+    CLTensor min_max = create_tensor<CLTensor>(shape_min_max, DataType::F32);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(min_max.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLDequantizationLayer dequant_layer;
+    dequant_layer.configure(&src, &dst, &min_max);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate valid region of min_max tensor
+    const ValidRegion valid_region_min_max = shape_to_valid_region(shape_min_max);
+    validate(min_max.info()->valid_region(), valid_region_min_max);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 4).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+
+    // Validate padding of min_max tensor
+    const PaddingSize padding_min_max = PaddingCalculator(shape_min_max.x(), 2).required_padding();
+    validate(min_max.info()->padding(), padding_min_max);
+}
+
+template <typename T>
+using CLDequantizationLayerFixture = DequantizationValidationFixture<CLTensor, CLAccessor, CLDequantizationLayer, T>;
+
+TEST_SUITE(Integer)
+TEST_SUITE(U8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLDequantizationLayerFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                                   framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLDequantizationLayerFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                                 framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/DirectConvolutionLayer.cpp b/tests/validation/CL/DirectConvolutionLayer.cpp
new file mode 100644
index 0000000..df42d0a
--- /dev/null
+++ b/tests/validation/CL/DirectConvolutionLayer.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLDirectConvolutionLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DirectConvolutionLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+// COMPMID-517 Invesitgate the mismatch to see whether it is a real bug
+RelativeTolerance<half>  tolerance_fp16(half(0.2)); /**< Tolerance for floating point tests */
+RelativeTolerance<float> tolerance_fp32(0.02f);     /**< Tolerance for floating point tests */
+constexpr float          tolerance_num = 0.07f;     /**< Tolerance number */
+
+constexpr AbsoluteTolerance<int8_t>  tolerance_qs8(0);  /**< Tolerance for fixed point tests */
+constexpr AbsoluteTolerance<int16_t> tolerance_qs16(0); /**< Tolerance for fixed point tests */
+
+/** Direct convolution data set. */
+const auto data_quantized = combine(datasets::SmallDirectConvolutionShapes(),
+                                    combine(framework::dataset::make("StrideX", 1, 3),
+                                            combine(framework::dataset::make("StrideY", 1, 3),
+                                                    combine(concat(combine(framework::dataset::make("PadX", 0),
+                                                                           combine(framework::dataset::make("PadY", 0),
+                                                                                   framework::dataset::make("KernelSize", 1))),
+                                                                   combine(framework::dataset::make("PadX", 0, 2),
+                                                                           combine(framework::dataset::make("PadY", 0, 2),
+                                                                                   framework::dataset::make("KernelSize", { 3 })))),
+                                                            framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
+
+const auto data = combine(datasets::SmallDirectConvolutionShapes(),
+                          combine(framework::dataset::make("StrideX", 1, 3),
+                                  combine(framework::dataset::make("StrideY", 1, 3),
+                                          combine(concat(combine(framework::dataset::make("PadX", 0),
+                                                                 combine(framework::dataset::make("PadY", 0),
+                                                                         framework::dataset::make("KernelSize", 1))),
+                                                         combine(framework::dataset::make("PadX", 0, 2),
+                                                                 combine(framework::dataset::make("PadY", 0, 2),
+                                                                         framework::dataset::make("KernelSize", { 3, 5 })))),
+                                                  framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(DirectConvolutionLayer)
+
+template <typename T>
+using CLDirectConvolutionLayerFixture = DirectConvolutionValidationFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<half>, framework::DatasetMode::ALL, combine(data, framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fp16, tolerance_num);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixture<float>, framework::DatasetMode::ALL, combine(data, framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fp32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLDirectConvolutionLayerFixedPointFixture = DirectConvolutionValidationFixedPointFixture<CLTensor, CLAccessor, CLDirectConvolutionLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::ALL, combine(combine(data_quantized, framework::dataset::make("DataType", DataType::QS8)),
+                                                                                                                    framework::dataset::make("FractionalBits", 2, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs8);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(Run, CLDirectConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(data_quantized, framework::dataset::make("DataType", DataType::QS16)),
+                                                                                                                     framework::dataset::make("FractionalBits", 2, 15)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/FillBorder.cpp b/tests/validation/CL/FillBorder.cpp
deleted file mode 100644
index 42b9064..0000000
--- a/tests/validation/CL/FillBorder.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "CL/CLAccessor.h"
-#include "CL/Helper.h"
-#include "Globals.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/CL/kernels/CLFillBorderKernel.h"
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/CL/CLScheduler.h"
-#include "arm_compute/runtime/CL/CLTensor.h"
-#include "arm_compute/runtime/CL/CLTensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::cl;
-using namespace arm_compute::test::validation;
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(CL)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(FillBorder, BorderModes() * boost::unit_test::data::make({ PaddingSize{ 0 }, PaddingSize{ 1, 0, 1, 2 }, PaddingSize{ 10 } }), border_mode, padding)
-{
-    constexpr uint8_t border_value = 42U;
-    constexpr uint8_t tensor_value = 89U;
-    BorderSize        border_size{ 5 };
-
-    // Create tensors
-    CLTensor src = create_tensor(TensorShape{ 10U, 10U, 2U }, DataType::U8);
-
-    src.info()->extend_padding(padding);
-
-    // Allocate tensor
-    src.allocator()->allocate();
-
-    // Check padding is as required
-    validate(src.info()->padding(), padding);
-
-    // Fill tensor with constant value
-    std::uniform_int_distribution<uint8_t> distribution{ tensor_value, tensor_value };
-    library->fill(CLAccessor(src), distribution, 0);
-
-    // Create and configure kernel
-    CLFillBorderKernel fill_border;
-    fill_border.configure(&src, border_size, border_mode, border_value);
-
-    // Run kernel
-    fill_border.run(fill_border.window(), CLScheduler::get().queue());
-
-    // Validate border
-    border_size.limit(padding);
-    validate(CLAccessor(src), border_size, border_mode, &border_value);
-
-    // Validate tensor
-    validate(CLAccessor(src), &tensor_value);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/CL/Flatten.cpp b/tests/validation/CL/Flatten.cpp
new file mode 100644
index 0000000..3350a72
--- /dev/null
+++ b/tests/validation/CL/Flatten.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLFlattenLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/FlattenLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(FlattenLayer)
+
+template <typename T>
+using CLFlattenLayerFixture = FlattenLayerValidationFixture<CLTensor, CLAccessor, CLFlattenLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFlattenLayerFixture<float>, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                    framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFlattenLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(framework::dataset::concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                        framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFlattenLayerFixture<half>, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                   framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFlattenLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(framework::dataset::concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                       framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFlattenLayerFixture<int8_t>, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                     framework::dataset::make("DataType", DataType::QS8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFlattenLayerFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(framework::dataset::concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                         framework::dataset::make("DataType", DataType::QS8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFlattenLayerFixture<int16_t>, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                      framework::dataset::make("DataType", DataType::QS16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFlattenLayerFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(framework::dataset::concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                          framework::dataset::make("DataType", DataType::QS16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/Floor.cpp b/tests/validation/CL/Floor.cpp
new file mode 100644
index 0000000..b8a93f0
--- /dev/null
+++ b/tests/validation/CL/Floor.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLFloor.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/FloorFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(Floor)
+
+template <typename T>
+using CLFloorFixture = FloorValidationFixture<CLTensor, CLAccessor, CLFloor, T>;
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFloorFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFloorFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/FullyConnectedLayer.cpp b/tests/validation/CL/FullyConnectedLayer.cpp
new file mode 100644
index 0000000..35b9d29
--- /dev/null
+++ b/tests/validation/CL/FullyConnectedLayer.cpp
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/FullyConnectedLayerDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/FullyConnectedLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+RelativeTolerance<float>            tolerance_f32(0.05f);
+RelativeTolerance<half_float::half> tolerance_f16(half(0.2));
+constexpr float                     tolerance_num = 0.07f; /**< Tolerance number */
+
+/** Tolerance for fixed point operations */
+constexpr AbsoluteTolerance<float> tolerance_fixed_point(1.f);
+
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
+{
+    DataType::F16,
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
+
+const auto FullyConnectedParameters = combine(framework::dataset::make("TransposeWeights", { false, true }), framework::dataset::make("ReshapeWeights", { false, true }));
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(FullyConnectedLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallFullyConnectedLayerDataset(), datasets::LargeFullyConnectedLayerDataset()),
+                                                                           FullyConnectedParameters),
+                                                                   CNNDataTypes),
+               src_shape, weights_shape, bias_shape, dst_shape, transpose_weights, reshape_weights, data_type)
+{
+    // Set fixed point position data type allowed
+    int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
+
+    TensorShape ws(weights_shape);
+
+    // Transpose weights if not done in the function
+    if(!reshape_weights || !transpose_weights)
+    {
+        const size_t shape_x = ws.x();
+        ws.set(0, ws.y());
+        ws.set(1, shape_x);
+    }
+
+    // Create tensors
+    CLTensor src     = create_tensor<CLTensor>(src_shape, data_type, 1, fixed_point_position);
+    CLTensor weights = create_tensor<CLTensor>(ws, data_type, 1, fixed_point_position);
+    CLTensor bias    = create_tensor<CLTensor>(bias_shape, data_type, 1, fixed_point_position);
+    CLTensor dst     = create_tensor<CLTensor>(dst_shape, data_type, 1, fixed_point_position);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function.
+    CLFullyConnectedLayer fc;
+    fc.configure(&src, &weights, &bias, &dst, transpose_weights, !reshape_weights);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(dst_shape);
+    validate(dst.info()->valid_region(), dst_valid_region);
+}
+
+template <typename T>
+using CLFullyConnectedLayerFixture = FullyConnectedLayerValidationFixture<CLTensor, CLAccessor, CLFullyConnectedLayer, T, false>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFullyConnectedLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallFullyConnectedLayerDataset(),
+                                                                                                                        FullyConnectedParameters),
+                                                                                                                framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFullyConnectedLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeFullyConnectedLayerDataset(),
+                                                                                                                      FullyConnectedParameters),
+                                                                                                              framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFullyConnectedLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallFullyConnectedLayerDataset(), FullyConnectedParameters),
+                                                                                                                 framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFullyConnectedLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeFullyConnectedLayerDataset(), FullyConnectedParameters),
+                                                                                                               framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLFullyConnectedLayerFixedPointFixture = FullyConnectedLayerValidationFixedPointFixture<CLTensor, CLAccessor, CLFullyConnectedLayer, T, false>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// Testing for fixed point position [1,6) as reciprocal limits the maximum fixed point position to 5
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFullyConnectedLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFullyConnectedLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 14
+FIXTURE_DATA_TEST_CASE(RunSmall, CLFullyConnectedLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLFullyConnectedLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/GEMM.cpp b/tests/validation/CL/GEMM.cpp
new file mode 100644
index 0000000..878f9fc
--- /dev/null
+++ b/tests/validation/CL/GEMM.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLGEMM.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/LargeGEMMDataset.h"
+#include "tests/datasets/SmallGEMMDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/GEMMFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+RelativeTolerance<float>            tolerance_f32(0.001f);    /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */
+RelativeTolerance<half_float::half> tolerance_f16(half(0.2)); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */
+constexpr AbsoluteTolerance<float>  tolerance_q(1.0f);        /**< Tolerance value for comparing reference's output against implementation's output for fixed point data types */
+constexpr float                     tolerance_num = 0.02f;    /**< Tolerance number */
+
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
+{
+    DataType::F16,
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(GEMM)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallGEMMDataset(), datasets::LargeGEMMDataset()), CNNDataTypes),
+               shape_a, shape_b, shape_c, output_shape, alpha, beta, data_type)
+{
+    // Set fixed point position data type allowed
+    const int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
+
+    // Create tensors
+    CLTensor a   = create_tensor<CLTensor>(shape_a, data_type, 1, fixed_point_position);
+    CLTensor b   = create_tensor<CLTensor>(shape_b, data_type, 1, fixed_point_position);
+    CLTensor c   = create_tensor<CLTensor>(shape_c, data_type, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(output_shape, data_type, 1, fixed_point_position);
+
+    ARM_COMPUTE_EXPECT(a.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(b.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(c.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLGEMM gemm;
+    gemm.configure(&a, &b, &c, &dst, alpha, beta);
+}
+
+template <typename T>
+using CLGEMMFixture = GEMMValidationFixture<CLTensor, CLAccessor, CLGEMM, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMFixture<half>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallGEMMDataset(), framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeGEMMDataset(), framework::dataset::make("DataType",
+                                                                                               DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallGEMMDataset(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeGEMMDataset(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLGEMMFixedPointFixture = GEMMValidationFixedPointFixture<CLTensor, CLAccessor, CLGEMM, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallGEMMDataset(),
+                                                                                                                     framework::dataset::make("DataType",
+                                                                                                                             DataType::QS8)),
+                                                                                                             framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeGEMMDataset(),
+                                                                                                                   framework::dataset::make("DataType",
+                                                                                                                           DataType::QS8)),
+                                                                                                           framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallGEMMDataset(),
+                                                                                                                      framework::dataset::make("DataType",
+                                                                                                                              DataType::QS16)),
+                                                                                                              framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLGEMMFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeGEMMDataset(),
+                                                                                                                    framework::dataset::make("DataType",
+                                                                                                                            DataType::QS16)),
+                                                                                                            framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/Gaussian3x3.cpp b/tests/validation/CL/Gaussian3x3.cpp
new file mode 100644
index 0000000..325afb4
--- /dev/null
+++ b/tests/validation/CL/Gaussian3x3.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/functions/CLGaussian3x3.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/Gaussian3x3Fixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr unsigned int filter_size = 3;              /* Size of the kernel/filter in number of elements. */
+constexpr BorderSize   border_size(filter_size / 2); /* Border size of the kernel/filter around its central element. */
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(Gaussian3x3)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+                                                                   datasets::BorderModes()),
+               shape, data_type, border_mode)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLGaussian3x3 gaussian3x3;
+    gaussian3x3.configure(&src, &dst, border_mode);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size);
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+    calculator.set_border_size(1);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-1);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst.info()->padding(), dst_padding);
+}
+
+template <typename T>
+using CLGaussian3x3Fixture = Gaussian3x3ValidationFixture<CLTensor, CLAccessor, CLGaussian3x3, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLGaussian3x3Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::U8)),
+                                                                                                           datasets::BorderModes()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLGaussian3x3Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                 DataType::U8)),
+                                                                                                         datasets::BorderModes()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/Gaussian5x5.cpp b/tests/validation/CL/Gaussian5x5.cpp
new file mode 100644
index 0000000..db5022e
--- /dev/null
+++ b/tests/validation/CL/Gaussian5x5.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/functions/CLGaussian5x5.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/Gaussian5x5Fixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr unsigned int filter_size = 5;              /* Size of the kernel/filter in number of elements. */
+constexpr BorderSize   border_size(filter_size / 2); /* Border size of the kernel/filter around its central element. */
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(Gaussian5x5)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+                                                                   datasets::BorderModes()),
+               shape, data_type, border_mode)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLGaussian5x5 gaussian5x5;
+    gaussian5x5.configure(&src, &dst, border_mode);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size);
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+    calculator.set_border_size(2);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-2);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst.info()->padding(), dst_padding);
+}
+
+template <typename T>
+using CLGaussian5x5Fixture = Gaussian5x5ValidationFixture<CLTensor, CLAccessor, CLGaussian5x5, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLGaussian5x5Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::U8)),
+                                                                                                           datasets::BorderModes()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLGaussian5x5Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                 DataType::U8)),
+                                                                                                         datasets::BorderModes()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/GlobalPooling.cpp b/tests/validation/CL/GlobalPooling.cpp
new file mode 100644
index 0000000..c5c9d00
--- /dev/null
+++ b/tests/validation/CL/GlobalPooling.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLPoolingLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/PoolingTypesDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/PoolingLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Input data set for float data types */
+const auto GlobalPoolingLayerDataset = combine(datasets::GlobalPoolingShapes(), datasets::PoolingTypes());
+
+/** Input data set for quantized data types */
+constexpr AbsoluteTolerance<float> tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for float types */
+constexpr AbsoluteTolerance<float> tolerance_f16(0.01f);  /**< Tolerance value for comparing reference's output against implementation's output for float types */
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(GlobalPoolingLayer)
+
+template <typename T>
+using CLGlobalPoolingLayerFixture = GlobalPoolingLayerValidationFixture<CLTensor, CLAccessor, CLPoolingLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunGlobalPooling, CLGlobalPoolingLayerFixture<float>, framework::DatasetMode::ALL, combine(GlobalPoolingLayerDataset, framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunGlobalPooling, CLGlobalPoolingLayerFixture<half>, framework::DatasetMode::ALL, combine(GlobalPoolingLayerDataset, framework::dataset::make("DataType",
+                                                                                                                 DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/HarrisCorners.cpp b/tests/validation/CL/HarrisCorners.cpp
new file mode 100644
index 0000000..4188cb5
--- /dev/null
+++ b/tests/validation/CL/HarrisCorners.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLArray.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLHarrisCorners.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/CL/CLArrayAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/HarrisCornersFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+const auto use_fp16 = framework::dataset::make("UseFP16",
+{ false });
+
+const auto data = combine(framework::dataset::make("GradientSize", { 3, 5, 7 }), combine(framework::dataset::make("BlockSize", { 3, 5, 7 }), combine(datasets::BorderModes(), use_fp16)));
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(HarrisCorners)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), data), framework::dataset::make("Format", Format::U8)), shape,
+               gradient_size, block_size, border_mode, use_fp16, format)
+{
+    ARM_COMPUTE_UNUSED(use_fp16);
+    ARM_COMPUTE_ERROR_ON(use_fp16);
+
+    std::mt19937                          gen(library->seed());
+    std::uniform_real_distribution<float> real_dist(0.f, 0.01f);
+
+    const float threshold   = real_dist(gen);
+    const float sensitivity = real_dist(gen);
+
+    constexpr float max_euclidean_distance = 30.f;
+    real_dist                              = std::uniform_real_distribution<float>(0.f, max_euclidean_distance);
+    const float min_dist                   = real_dist(gen);
+
+    // Generate a random constant value
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type_from_format(format));
+    src.info()->set_format(format);
+    CLKeyPointArray corners;
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create harris corners configure function
+    CLHarrisCorners harris_corners;
+    harris_corners.configure(&src, threshold, min_dist, sensitivity, gradient_size, block_size, &corners, border_mode, constant_border_value);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(gradient_size / 2);
+    calculator.set_access_offset(-gradient_size / 2);
+    calculator.set_accessed_elements(16);
+
+    const PaddingSize padding = calculator.required_padding();
+
+    validate(src.info()->padding(), padding);
+}
+
+template <typename T>
+using CLHarrisCornersFixture = HarrisCornersValidationFixture<CLTensor, CLAccessor, CLKeyPointArray, CLHarrisCorners, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLHarrisCornersFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), data), framework::dataset::make("Format", Format::U8)))
+{
+    // Validate output
+    CLArrayAccessor<KeyPoint> array(_target);
+    validate_keypoints(array.buffer(), array.buffer() + array.num_values(), _reference.begin(), _reference.end(), RelativeTolerance<float>(0.0001f));
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLHarrisCornersFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), data), framework::dataset::make("Format", Format::U8)))
+{
+    // Validate output
+    CLArrayAccessor<KeyPoint> array(_target);
+    validate_keypoints(array.buffer(), array.buffer() + array.num_values(), _reference.begin(), _reference.end(), RelativeTolerance<float>(0.0001f));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/IntegralImage.cpp b/tests/validation/CL/IntegralImage.cpp
new file mode 100644
index 0000000..1a6d397
--- /dev/null
+++ b/tests/validation/CL/IntegralImage.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/CL/functions/CLIntegralImage.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/IntegralImageFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(IntegralImage)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::U32);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLIntegralImage integral_image;
+    integral_image.configure(&src, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+template <typename T>
+using CLIntegralImageFixture = IntegralImageValidationFixture<CLTensor, CLAccessor, CLIntegralImage, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLIntegralImageFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                             DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLIntegralImageFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                           DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/L2Normalize.cpp b/tests/validation/CL/L2Normalize.cpp
new file mode 100644
index 0000000..4b0820c
--- /dev/null
+++ b/tests/validation/CL/L2Normalize.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLL2Normalize.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/L2NormalizeFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+constexpr AbsoluteTolerance<float> tolerance_f32(0.00001f);
+
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(L2Normalize)
+
+template <typename T>
+using CLL2NormalizeFixture = L2NormalizeValidationFixture<CLTensor, CLAccessor, CLL2Normalize, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLL2NormalizeFixture<float>, framework::DatasetMode::PRECOMMIT,
+                       combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), framework::dataset::make("Epsilon", { 1e-12 })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLL2NormalizeFixture<float>, framework::DatasetMode::NIGHTLY,
+                       combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), framework::dataset::make("Epsilon", { 1e-12 })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/MeanStdDev.cpp b/tests/validation/CL/MeanStdDev.cpp
new file mode 100644
index 0000000..92d87e0
--- /dev/null
+++ b/tests/validation/CL/MeanStdDev.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/CL/functions/CLMeanStdDev.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/MeanStdDevFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+RelativeTolerance<float> tolerance_rel_high_error(0.05f);
+RelativeTolerance<float> tolerance_rel_low_error(0.0005f);
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(MeanStdDev)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+
+    // Create output variables
+    float mean    = 0.f;
+    float std_dev = 0.f;
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create configure function
+    CLMeanStdDev mean_std_dev_image;
+    mean_std_dev_image.configure(&src, &mean, &std_dev);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 8).required_padding();
+    validate(src.info()->padding(), padding);
+}
+
+template <typename T>
+using CLMeanStdDevFixture = MeanStdDevValidationFixture<CLTensor, CLAccessor, CLMeanStdDev, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLMeanStdDevFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
+{
+    // Validate mean output
+    validate(_target.first, _reference.first);
+
+    // Validate std_dev output
+    validate(_target.second, _reference.second, tolerance_rel_high_error);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLMeanStdDevFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate mean output
+    validate(_target.first, _reference.first, tolerance_rel_low_error);
+
+    // Validate std_dev output
+    validate(_target.second, _reference.second, tolerance_rel_high_error);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/MinMaxLocation.cpp b/tests/validation/CL/MinMaxLocation.cpp
new file mode 100644
index 0000000..acc4cbf
--- /dev/null
+++ b/tests/validation/CL/MinMaxLocation.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/CL/functions/CLMinMaxLocation.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/CL/CLArrayAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/MinMaxLocationFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(MinMaxLocation)
+
+template <typename T>
+using CLMinMaxLocationFixture = MinMaxLocationValidationFixture<CLTensor, CLAccessor, CLArray<Coordinates2D>, CLArrayAccessor<Coordinates2D>, CLMinMaxLocation, T>;
+
+void validate_configuration(const CLTensor &src, TensorShape shape)
+{
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create output storage
+    int32_t              min = 0;
+    int32_t              max = 0;
+    CLCoordinates2DArray min_loc(shape.total_size());
+    CLCoordinates2DArray max_loc(shape.total_size());
+
+    // Create and configure function
+    CLMinMaxLocation min_max_loc;
+    min_max_loc.configure(&src, &min, &max, &min_loc, &max_loc);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+}
+
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    src.info()->set_format(Format::U8);
+
+    validate_configuration(src, shape);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLMinMaxLocationFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                              DataType::U8)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLMinMaxLocationFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::U8)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+TEST_SUITE_END() // U8
+
+TEST_SUITE(S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::S16)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    src.info()->set_format(Format::S16);
+
+    validate_configuration(src, shape);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLMinMaxLocationFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                              DataType::S16)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLMinMaxLocationFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::S16)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+TEST_SUITE_END() // S16
+
+TEST_SUITE(Float)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::F32)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    src.info()->set_format(Format::F32);
+
+    validate_configuration(src, shape);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLMinMaxLocationFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::F32)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLMinMaxLocationFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::F32)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+TEST_SUITE_END() // F32
+
+TEST_SUITE_END() // MinMaxLocation
+TEST_SUITE_END() // CL
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/NonLinearFilter.cpp b/tests/validation/CL/NonLinearFilter.cpp
new file mode 100644
index 0000000..ad26b8e
--- /dev/null
+++ b/tests/validation/CL/NonLinearFilter.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/CL/functions/CLNonLinearFilter.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/MatrixPatternDataset.h"
+#include "tests/datasets/NonLinearFilterFunctionDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/NonLinearFilterFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(NonLinearFilter)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), datasets::NonLinearFilterFunctions()),
+                                                                                   framework::dataset::make("MaskSize", { 3U, 5U })),
+                                                                           datasets::MatrixPatterns()),
+                                                                   datasets::BorderModes()),
+               shape, function, mask_size, pattern, border_mode)
+{
+    std::mt19937                           generator(library->seed());
+    std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
+    const uint8_t                          constant_border_value = distribution_u8(generator);
+
+    // Create the mask
+    uint8_t mask[mask_size * mask_size];
+    fill_mask_from_pattern(mask, mask_size, mask_size, pattern);
+    const auto half_mask_size = static_cast<int>(mask_size / 2);
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, DataType::U8);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::U8);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLNonLinearFilter filter;
+    filter.configure(&src, &dst, function, mask_size, pattern, mask, border_mode, constant_border_value);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, BorderSize(half_mask_size));
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), ((MatrixPattern::OTHER == pattern) ? 1 : 8));
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(half_mask_size);
+
+    const PaddingSize write_padding = calculator.required_padding(PaddingCalculator::Option::EXCLUDE_BORDER);
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-half_mask_size);
+
+    const PaddingSize read_padding = calculator.required_padding(PaddingCalculator::Option::INCLUDE_BORDER);
+
+    validate(src.info()->padding(), read_padding);
+    validate(dst.info()->padding(), write_padding);
+}
+
+template <typename T>
+using CLNonLinearFilterFixture = NonLinearFilterValidationFixture<CLTensor, CLAccessor, CLNonLinearFilter, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLNonLinearFilterFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(combine(datasets::SmallShapes(),
+                                                                                                                       datasets::NonLinearFilterFunctions()),
+                                                                                                                       framework::dataset::make("MaskSize", { 3U, 5U })),
+                                                                                                                       datasets::MatrixPatterns()),
+                                                                                                                       datasets::BorderModes()),
+                                                                                                               framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), _border_size));
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLNonLinearFilterFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(datasets::LargeShapes(),
+                                                                                                                     datasets::NonLinearFilterFunctions()),
+                                                                                                                     framework::dataset::make("MaskSize", { 3U, 5U })),
+                                                                                                                     datasets::MatrixPatterns()),
+                                                                                                                     datasets::BorderModes()),
+                                                                                                             framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), _border_size));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/NormalizationLayer.cpp b/tests/validation/CL/NormalizationLayer.cpp
new file mode 100644
index 0000000..9db27ef
--- /dev/null
+++ b/tests/validation/CL/NormalizationLayer.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLNormalizationLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/NormalizationTypesDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/NormalizationLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+RelativeTolerance<half>  tolerance_f16(half(0.2));
+RelativeTolerance<float> tolerance_f32(0.05f);
+
+/** Tolerance for fixed point operations */
+constexpr AbsoluteTolerance<int8_t>  tolerance_qs8(2);
+constexpr AbsoluteTolerance<int16_t> tolerance_qs16(3);
+
+/** Input data set. */
+const auto NormalizationDataset = combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("NormType", { NormType::IN_MAP_1D, NormType::CROSS_MAP })),
+                                                  framework::dataset::make("NormalizationSize", 3, 9, 2)),
+                                          framework::dataset::make("Beta", { 0.5f, 1.f, 2.f }));
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(NormalizationLayer)
+
+template <typename T>
+using CLNormalizationLayerFixture = NormalizationValidationFixture<CLTensor, CLAccessor, CLNormalizationLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLNormalizationLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLNormalizationLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLNormalizationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLNormalizationLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLNormalizationLayerFixedPointFixture = NormalizationValidationFixedPointFixture<CLTensor, CLAccessor, CLNormalizationLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// Testing for fixed point position [1,6) as reciprocal limits the maximum fixed point position to 5
+FIXTURE_DATA_TEST_CASE(RunSmall, CLNormalizationLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs8);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLNormalizationLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs8);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 5
+FIXTURE_DATA_TEST_CASE(RunSmall, CLNormalizationLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLNormalizationLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/PoolingLayer.cpp b/tests/validation/CL/PoolingLayer.cpp
new file mode 100644
index 0000000..44617f6
--- /dev/null
+++ b/tests/validation/CL/PoolingLayer.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLPoolingLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/PoolingTypesDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/PoolingLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Input data set for float data types */
+const auto PoolingLayerDatasetFP = combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { 2, 3, 7, 9 })),
+                                           framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) }));
+
+/** Input data set for quantized data types */
+const auto PoolingLayerDatasetQS = combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { 2, 3 })),
+                                           framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) }));
+
+constexpr AbsoluteTolerance<float> tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for float types */
+constexpr AbsoluteTolerance<float> tolerance_f16(0.01f);  /**< Tolerance value for comparing reference's output against implementation's output for float types */
+constexpr AbsoluteTolerance<float> tolerance_qs8(3);      /**< Tolerance value for comparing reference's output against implementation's output for quantized input */
+constexpr AbsoluteTolerance<float> tolerance_qs16(6);     /**< Tolerance value for comparing reference's output against implementation's output for quantized input */
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(PoolingLayer)
+
+template <typename T>
+using CLPoolingLayerFixture = PoolingLayerValidationFixture<CLTensor, CLAccessor, CLPoolingLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLPoolingLayerFixture<float>, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), combine(PoolingLayerDatasetFP, framework::dataset::make("DataType",
+                                                                                                    DataType::F32))))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLPoolingLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), combine(PoolingLayerDatasetFP, framework::dataset::make("DataType",
+                                                                                                        DataType::F32))))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLPoolingLayerFixture<half>, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), combine(PoolingLayerDatasetFP,
+                                                                                                   framework::dataset::make("DataType", DataType::F16))))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLPoolingLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), combine(PoolingLayerDatasetFP,
+                                                                                                       framework::dataset::make("DataType", DataType::F16))))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLPoolingLayerFixedPointFixture = PoolingLayerValidationFixedPointFixture<CLTensor, CLAccessor, CLPoolingLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLPoolingLayerFixedPointFixture<int8_t>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                       framework::dataset::make("DataType", DataType::QS8))),
+                                                                                                               framework::dataset::make("FractionalBits", 1, 4)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs8);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLPoolingLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                   framework::dataset::make("DataType", DataType::QS8))),
+                                                                                                                   framework::dataset::make("FractionalBits", 1, 4)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs8);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLPoolingLayerFixedPointFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                        framework::dataset::make("DataType", DataType::QS16))),
+                                                                                                                framework::dataset::make("FractionalBits", 1, 12)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLPoolingLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                    framework::dataset::make("DataType", DataType::QS16))),
+                                                                                                                    framework::dataset::make("FractionalBits", 1, 12)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qs16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/QuantizationLayer.cpp b/tests/validation/CL/QuantizationLayer.cpp
new file mode 100644
index 0000000..0747fe9
--- /dev/null
+++ b/tests/validation/CL/QuantizationLayer.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLQuantizationLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/QuantizationLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr AbsoluteTolerance<float> tolerance_f32(1.0f); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */
+const auto                         QuantizationShapes = concat(concat(concat(datasets::Small3DShapes(),
+                                                                             datasets::Large3DShapes()),
+                                                                      datasets::Small4DShapes()),
+                                                               datasets::Large4DShapes());
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(QuantizationLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(QuantizationShapes, framework::dataset::make("DataType", DataType::F32)), shape, data_type)
+{
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, DataType::U8);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLQuantizationLayer quant_layer;
+    quant_layer.configure(&src, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 4).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+template <typename T>
+using CLQuantizationLayerFixture = QuantizationValidationFixture<CLTensor, CLAccessor, CLQuantizationLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLQuantizationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                               framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLQuantizationLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                             framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/ReductionOperation.cpp b/tests/validation/CL/ReductionOperation.cpp
new file mode 100644
index 0000000..684ed46
--- /dev/null
+++ b/tests/validation/CL/ReductionOperation.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLReductionOperation.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ReductionOperationDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ReductionOperationFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+RelativeTolerance<float> tolerance_f32(0.00001f);
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(ReductionOperation)
+
+template <typename T>
+using CLReductionOperationFixture = ReductionOperationValidationFixture<CLTensor, CLAccessor, CLReductionOperation, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLReductionOperationFixture<float>, framework::DatasetMode::PRECOMMIT,
+                       combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), datasets::ReductionOperations()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLReductionOperationFixture<float>, framework::DatasetMode::NIGHTLY,
+                       combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), datasets::ReductionOperations()))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/ReshapeLayer.cpp b/tests/validation/CL/ReshapeLayer.cpp
new file mode 100644
index 0000000..57027a9
--- /dev/null
+++ b/tests/validation/CL/ReshapeLayer.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLReshapeLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ReshapeLayerDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ReshapeLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(ReshapeLayer)
+
+template <typename T>
+using CLReshapeLayerFixture = ReshapeLayerValidationFixture<CLTensor, CLAccessor, CLReshapeLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(F32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLReshapeLayerFixture<float>, framework::DatasetMode::ALL, combine(datasets::SmallReshapeLayerDataset(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(F16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLReshapeLayerFixture<half>, framework::DatasetMode::ALL, combine(datasets::SmallReshapeLayerDataset(), framework::dataset::make("DataType",
+                                                                                                   DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Integer)
+TEST_SUITE(S8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLReshapeLayerFixture<int8_t>, framework::DatasetMode::ALL, combine(datasets::SmallReshapeLayerDataset(), framework::dataset::make("DataType", DataType::S8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(S16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLReshapeLayerFixture<int16_t>, framework::DatasetMode::ALL, combine(datasets::SmallReshapeLayerDataset(), framework::dataset::make("DataType", DataType::S16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/SYSTEM/AlexNet.cpp b/tests/validation/CL/SYSTEM/AlexNet.cpp
new file mode 100644
index 0000000..75f8d19
--- /dev/null
+++ b/tests/validation/CL/SYSTEM/AlexNet.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/CL/CLSubTensor.h"
+#include "arm_compute/runtime/CL/functions/CLActivationLayer.h"
+#include "arm_compute/runtime/CL/functions/CLConvolutionLayer.h"
+#include "arm_compute/runtime/CL/functions/CLDirectConvolutionLayer.h"
+#include "arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h"
+#include "arm_compute/runtime/CL/functions/CLNormalizationLayer.h"
+#include "arm_compute/runtime/CL/functions/CLPoolingLayer.h"
+#include "arm_compute/runtime/CL/functions/CLSoftmaxLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/networks/AlexNetNetwork.h"
+#include "tests/validation/Validation.h"
+
+#include <string>
+#include <vector>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+using CLAlexNetModel = networks::AlexNetNetwork<ICLTensor,
+      CLTensor,
+      CLSubTensor,
+      CLAccessor,
+      CLActivationLayer,
+      CLConvolutionLayer,
+      CLDirectConvolutionLayer,
+      CLFullyConnectedLayer,
+      CLNormalizationLayer,
+      CLPoolingLayer,
+      CLSoftmaxLayer>;
+std::vector<unsigned int> compute_alexnet(DataType dt, unsigned int batches, std::string input_file)
+{
+    std::vector<std::string> weight_files = { "cnn_data/alexnet_model/conv1_w.npy",
+                                              "cnn_data/alexnet_model/conv2_w.npy",
+                                              "cnn_data/alexnet_model/conv3_w.npy",
+                                              "cnn_data/alexnet_model/conv4_w.npy",
+                                              "cnn_data/alexnet_model/conv5_w.npy",
+                                              "cnn_data/alexnet_model/fc6_w.npy",
+                                              "cnn_data/alexnet_model/fc7_w.npy",
+                                              "cnn_data/alexnet_model/fc8_w.npy"
+                                            };
+
+    std::vector<std::string> bias_files = { "cnn_data/alexnet_model/conv1_b.npy",
+                                            "cnn_data/alexnet_model/conv2_b.npy",
+                                            "cnn_data/alexnet_model/conv3_b.npy",
+                                            "cnn_data/alexnet_model/conv4_b.npy",
+                                            "cnn_data/alexnet_model/conv5_b.npy",
+                                            "cnn_data/alexnet_model/fc6_b.npy",
+                                            "cnn_data/alexnet_model/fc7_b.npy",
+                                            "cnn_data/alexnet_model/fc8_b.npy"
+                                          };
+    CLAlexNetModel network{};
+    network.init(dt, 4, batches);
+    network.build();
+    network.allocate();
+    network.fill(weight_files, bias_files);
+    network.feed(std::move(input_file));
+    network.run();
+
+    return network.get_classifications();
+}
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(SYSTEM_TESTS)
+
+TEST_CASE(AlexNet, framework::DatasetMode::PRECOMMIT)
+{
+    // Compute alexnet
+    std::vector<unsigned int> classified_labels = compute_alexnet(DataType::F32, 1, "cnn_data/imagenet_data/cat.npy");
+
+    // Expected labels
+    std::vector<unsigned int> expected_labels = { 281 };
+
+    // Validate labels
+    validate(classified_labels, expected_labels);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/SYSTEM/LeNet5.cpp b/tests/validation/CL/SYSTEM/LeNet5.cpp
new file mode 100644
index 0000000..92dcdea
--- /dev/null
+++ b/tests/validation/CL/SYSTEM/LeNet5.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/CL/functions/CLActivationLayer.h"
+#include "arm_compute/runtime/CL/functions/CLConvolutionLayer.h"
+#include "arm_compute/runtime/CL/functions/CLFullyConnectedLayer.h"
+#include "arm_compute/runtime/CL/functions/CLPoolingLayer.h"
+#include "arm_compute/runtime/CL/functions/CLSoftmaxLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/networks/LeNet5Network.h"
+#include "tests/validation/Validation.h"
+
+#include <string>
+#include <vector>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+using CLLeNet5Model = networks::LeNet5Network<CLTensor,
+      CLAccessor,
+      CLActivationLayer,
+      CLConvolutionLayer,
+      CLFullyConnectedLayer,
+      CLPoolingLayer,
+      CLSoftmaxLayer>;
+std::vector<unsigned int> compute_lenet5(unsigned int batches, std::string input_file)
+{
+    std::vector<std::string> weight_files = { "cnn_data/lenet_model/conv1_w.npy",
+                                              "cnn_data/lenet_model/conv2_w.npy",
+                                              "cnn_data/lenet_model/ip1_w.npy",
+                                              "cnn_data/lenet_model/ip2_w.npy"
+                                            };
+
+    std::vector<std::string> bias_files = { "cnn_data/lenet_model/conv1_b.npy",
+                                            "cnn_data/lenet_model/conv2_b.npy",
+                                            "cnn_data/lenet_model/ip1_b.npy",
+                                            "cnn_data/lenet_model/ip2_b.npy"
+                                          };
+    CLLeNet5Model network{};
+    network.init(batches);
+    network.build();
+    network.allocate();
+    network.fill(weight_files, bias_files);
+    network.feed(std::move(input_file));
+    network.run();
+
+    return network.get_classifications();
+}
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(SYSTEM_TESTS)
+
+TEST_CASE(LeNet5, framework::DatasetMode::PRECOMMIT)
+{
+    // Compute alexnet
+    std::vector<unsigned int> classified_labels = compute_lenet5(10, "cnn_data/mnist_data/input10.npy");
+
+    // Expected labels
+    std::vector<unsigned int> expected_labels = { 7, 2, 1, 0, 4, 1, 4, 9, 5, 9 };
+
+    // Validate labels
+    validate(classified_labels, expected_labels);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/Scale.cpp b/tests/validation/CL/Scale.cpp
new file mode 100644
index 0000000..f43f2ae
--- /dev/null
+++ b/tests/validation/CL/Scale.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Helpers.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/functions/CLScale.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Helpers.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ScaleFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** CNN data types */
+const auto ScaleDataTypes = framework::dataset::make("DataType",
+{
+    DataType::U8,
+    DataType::S16,
+    DataType::F16,
+    DataType::F32,
+});
+
+/** Tolerance */
+constexpr AbsoluteTolerance<uint8_t> tolerance_u8(1);
+constexpr AbsoluteTolerance<int16_t> tolerance_s16(1);
+RelativeTolerance<float>             tolerance_f32(0.05);
+RelativeTolerance<half>              tolerance_f16(half(0.1));
+
+constexpr float tolerance_num_f32(0.01f);
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(Scale)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::MediumShapes(), datasets::LargeShapes()), ScaleDataTypes),
+                                                                           framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                   datasets::BorderModes()),
+               shape, data_type, policy, border_mode)
+{
+    std::mt19937                           generator(library->seed());
+    std::uniform_real_distribution<float>  distribution_float(0.25, 2);
+    const float                            scale_x = distribution_float(generator);
+    const float                            scale_y = distribution_float(generator);
+    std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
+    uint8_t                                constant_border_value = distribution_u8(generator);
+
+    // Create tensors
+    CLTensor    src = create_tensor<CLTensor>(shape, data_type);
+    TensorShape shape_scaled(shape);
+    shape_scaled.set(0, shape[0] * scale_x);
+    shape_scaled.set(1, shape[1] * scale_y);
+    CLTensor dst = create_tensor<CLTensor>(shape_scaled, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLScale clscale;
+    clscale.configure(&src, &dst, policy, border_mode, constant_border_value);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = calculate_valid_region_scale(*(src.info()), shape_scaled, policy, BorderSize(1), (border_mode == BorderMode::UNDEFINED));
+
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape_scaled.x(), 4);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize read_padding(1);
+    const PaddingSize write_padding = calculator.required_padding(PaddingCalculator::Option::EXCLUDE_BORDER);
+    validate(src.info()->padding(), read_padding);
+    validate(dst.info()->padding(), write_padding);
+}
+
+template <typename T>
+using CLScaleFixture = ScaleValidationFixture<CLTensor, CLAccessor, CLScale, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)),
+                                                                                                     framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                             datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)),
+                                                                                                         framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                                 datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)),
+                                                                                                    framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                            datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_f16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                DataType::F16)),
+                                                                                                        framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                                datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_f16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Integer)
+TEST_SUITE(U8)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)),
+                                                                                                       framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                               datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_u8);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::U8)),
+                                                                                                           framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                                   datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_u8);
+}
+TEST_SUITE_END()
+TEST_SUITE(S16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLScaleFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::S16)),
+                                                                                                       framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                               datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_s16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLScaleFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::S16)),
+                                                                                                           framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                                   datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo        src_info(_shape, 1, _data_type);
+    const ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(CLAccessor(_target), _reference, valid_region, tolerance_s16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/Sobel.cpp b/tests/validation/CL/Sobel.cpp
new file mode 100644
index 0000000..cde93e7
--- /dev/null
+++ b/tests/validation/CL/Sobel.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLSobel3x3.h"
+#include "arm_compute/runtime/CL/functions/CLSobel5x5.h"
+#include "arm_compute/runtime/CL/functions/CLSobel7x7.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/SobelFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(Sobel)
+
+TEST_SUITE(W3x3)
+using CLSobel3x3Fixture = SobelValidationFixture<CLTensor, CLAccessor, CLSobel3x3, uint8_t, int16_t>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                   Format::U8)),
+               shape, border_mode, format)
+{
+    // Generate a random constant value
+    std::mt19937                           gen(library->seed());
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    CLTensor src   = create_tensor<CLTensor>(shape, data_type_from_format(format));
+    CLTensor dst_x = create_tensor<CLTensor>(shape, DataType::S16);
+    CLTensor dst_y = create_tensor<CLTensor>(shape, DataType::S16);
+
+    src.info()->set_format(format);
+    dst_x.info()->set_format(Format::S16);
+    dst_y.info()->set_format(Format::S16);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create sobel 3x3 configure function
+    CLSobel3x3 sobel;
+    sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
+
+    // Validate valid region
+    constexpr BorderSize border_size{ 1 };
+    const ValidRegion    dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, border_size);
+
+    validate(dst_x.info()->valid_region(), dst_valid_region);
+    validate(dst_y.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(1);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-1);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst_x.info()->padding(), dst_padding);
+    validate(dst_y.info()->padding(), dst_padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLSobel3x3Fixture, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                               Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(CLAccessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(CLAccessor(_target.second), _reference.second, valid_region_y);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLSobel3x3Fixture, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                             Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(CLAccessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(CLAccessor(_target.second), _reference.second, valid_region_y);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(W5x5)
+using CLSobel5x5Fixture = SobelValidationFixture<CLTensor, CLAccessor, CLSobel5x5, uint8_t, int16_t>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                   Format::U8)),
+               shape, border_mode, format)
+{
+    // Generate a random constant value
+    std::mt19937                           gen(library->seed());
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    CLTensor src   = create_tensor<CLTensor>(shape, data_type_from_format(format));
+    CLTensor dst_x = create_tensor<CLTensor>(shape, DataType::S16);
+    CLTensor dst_y = create_tensor<CLTensor>(shape, DataType::S16);
+
+    src.info()->set_format(format);
+    dst_x.info()->set_format(Format::S16);
+    dst_y.info()->set_format(Format::S16);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create sobel 5x5 configure function
+    CLSobel5x5 sobel;
+    sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
+
+    // Validate valid region
+    constexpr BorderSize border_size{ 2 };
+    const ValidRegion    dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, border_size);
+
+    validate(dst_x.info()->valid_region(), dst_valid_region);
+    validate(dst_y.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(2);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-2);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst_x.info()->padding(), dst_padding);
+    validate(dst_y.info()->padding(), dst_padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLSobel5x5Fixture, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                               Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(CLAccessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(CLAccessor(_target.second), _reference.second, valid_region_y);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLSobel5x5Fixture, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                             Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(CLAccessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(CLAccessor(_target.second), _reference.second, valid_region_y);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(W7x7)
+using CLSobel7x7Fixture = SobelValidationFixture<CLTensor, CLAccessor, CLSobel7x7, uint8_t, int32_t>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                   Format::U8)),
+               shape, border_mode, format)
+{
+    // Generate a random constant value
+    std::mt19937                           gen(library->seed());
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    CLTensor src   = create_tensor<CLTensor>(shape, data_type_from_format(format));
+    CLTensor dst_x = create_tensor<CLTensor>(shape, DataType::S32);
+    CLTensor dst_y = create_tensor<CLTensor>(shape, DataType::S32);
+
+    src.info()->set_format(format);
+    dst_x.info()->set_format(Format::S32);
+    dst_y.info()->set_format(Format::S32);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create sobel 7x7 configure function
+    CLSobel7x7 sobel;
+    sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
+
+    // Validate valid region
+    constexpr BorderSize border_size{ 3 };
+    const ValidRegion    dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, border_size);
+
+    validate(dst_x.info()->valid_region(), dst_valid_region);
+    validate(dst_y.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(3);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-3);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst_x.info()->padding(), dst_padding);
+    validate(dst_y.info()->padding(), dst_padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLSobel7x7Fixture, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                               Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(CLAccessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(CLAccessor(_target.second), _reference.second, valid_region_y);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLSobel7x7Fixture, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                             Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(CLAccessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(CLAccessor(_target.second), _reference.second, valid_region_y);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/SoftmaxLayer.cpp b/tests/validation/CL/SoftmaxLayer.cpp
new file mode 100644
index 0000000..c469b8a
--- /dev/null
+++ b/tests/validation/CL/SoftmaxLayer.cpp
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLSoftmaxLayer.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/SoftmaxLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+RelativeTolerance<half>  tolerance_f16(half(0.2));
+RelativeTolerance<float> tolerance_f32(0.001f);
+
+/** Tolerance for fixed point operations */
+constexpr AbsoluteTolerance<int16_t> tolerance_fixed_point(2);
+
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
+{
+    DataType::F16,
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
+} // namespace
+
+TEST_SUITE(CL)
+TEST_SUITE(SoftmaxLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), CNNDataTypes), shape, data_type)
+{
+    // Set fixed point position data type allowed
+    const int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type, 1, fixed_point_position);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type, 1, fixed_point_position);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    CLSoftmaxLayer smx_layer;
+    smx_layer.configure(&src, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+template <typename T>
+using CLSoftmaxLayerFixture = SoftmaxValidationFixture<CLTensor, CLAccessor, CLSoftmaxLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLSoftmaxLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLSoftmaxLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f16);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, CLSoftmaxLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLSoftmaxLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using CLSoftmaxLayerFixedPointFixture = SoftmaxValidationFixedPointFixture<CLTensor, CLAccessor, CLSoftmaxLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// Testing for fixed point position [1,6) as reciprocal limits the maximum fixed point position to 5
+FIXTURE_DATA_TEST_CASE(RunSmall, CLSoftmaxLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                                     DataType::QS8)),
+                                                                                                                     framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLSoftmaxLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::QS8)),
+                                                                                                                   framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 14
+FIXTURE_DATA_TEST_CASE(RunSmall, CLSoftmaxLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(),
+                                                                                                                      framework::dataset::make("DataType",
+                                                                                                                              DataType::QS16)),
+                                                                                                                      framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, CLSoftmaxLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(),
+                                                                                                                    framework::dataset::make("DataType",
+                                                                                                                            DataType::QS16)),
+                                                                                                                    framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_fixed_point);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/TableLookup.cpp b/tests/validation/CL/TableLookup.cpp
new file mode 100644
index 0000000..c2b2386
--- /dev/null
+++ b/tests/validation/CL/TableLookup.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLTableLookup.h"
+
+#include "tests/CL/CLAccessor.h"
+#include "tests/CL/CLLutAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+
+#include "tests/validation/Helpers.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/TableLookupFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(TableLookup)
+
+template <typename T>
+using CLTableLookupFixture = TableLookupValidationFixture<CLTensor, CLAccessor, CLTableLookup, CLLutAccessor<T>, CLLut, T>;
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
+               shape, data_type)
+{
+    // Create Lut
+    const int num_elem = (data_type == DataType::U8) ? std::numeric_limits<uint8_t>::max() + 1 : std::numeric_limits<int16_t>::max() - std::numeric_limits<int16_t>::lowest() + 1;
+    CLLut     cllut(num_elem, data_type);
+
+    switch(data_type)
+    {
+        case DataType::U8:
+            fill_lookuptable(CLLutAccessor<uint8_t>(cllut));
+            break;
+        case DataType::S16:
+            fill_lookuptable(CLLutAccessor<int16_t>(cllut));
+            break;
+        default:
+            ARM_COMPUTE_ERROR("Not supported");
+    }
+
+    // Create tensors
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type);
+
+    // Create and Configure function
+    CLTableLookup table_lookup;
+    table_lookup.configure(&src, &cllut, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 8).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallU8, CLTableLookupFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeU8, CLTableLookupFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(S16)
+FIXTURE_DATA_TEST_CASE(RunSmallS16, CLTableLookupFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::S16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeS16, CLTableLookupFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::S16)))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/Threshold.cpp b/tests/validation/CL/Threshold.cpp
index a8c77ec..8f0150e 100644
--- a/tests/validation/CL/Threshold.cpp
+++ b/tests/validation/CL/Threshold.cpp
@@ -21,134 +21,70 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "CL/CLAccessor.h"
-#include "CL/Helper.h"
-#include "Globals.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "dataset/ThresholdDataset.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/CL/CLTensor.h"
-#include "arm_compute/runtime/CL/CLTensorAllocator.h"
 #include "arm_compute/runtime/CL/functions/CLThreshold.h"
+#include "tests/CL/CLAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/datasets/ThresholdDataset.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ThresholdFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::cl;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Threshold function.
- *
- * @param[in] shape       Shape of the input and output tensors.
- * @param[in] threshold   Threshold. When the threshold type is RANGE, this is used as the lower threshold.
- * @param[in] false_value value to set when the condition is not respected.
- * @param[in] true_value  value to set when the condition is respected.
- * @param[in] type        Thresholding type. Either RANGE or BINARY.
- * @param[in] upper       Upper threshold. Only used when the thresholding type is RANGE.
- *
- * @return Computed output tensor.
- */
-CLTensor compute_threshold(const TensorShape &shape, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(CL)
+TEST_SUITE(Threshold)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), datasets::MixedThresholdDataset()),
+                                                                   framework::dataset::make("DataType", DataType::U8)),
+               shape, threshold, false_value, true_value, type, upper, data_type)
 {
     // Create tensors
-    CLTensor src = create_tensor(shape, DataType::U8);
-    CLTensor dst = create_tensor(shape, DataType::U8);
+    CLTensor src = create_tensor<CLTensor>(shape, data_type);
+    CLTensor dst = create_tensor<CLTensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
     CLThreshold thrsh;
     thrsh.configure(&src, &dst, threshold, false_value, true_value, type, upper);
 
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(CLAccessor(src), 0);
-
-    // Compute function
-    thrsh.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(CL)
-BOOST_AUTO_TEST_SUITE(Threshold)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration,
-                     (SmallShapes() + LargeShapes()) * ThresholdDataset(),
-                     shape, threshold_conf)
-{
-    // Create tensors
-    CLTensor src = create_tensor(shape, DataType::U8);
-    CLTensor dst = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    CLThreshold cl_threshold;
-    cl_threshold.configure(&src, &dst, threshold_conf.threshold, threshold_conf.false_value, threshold_conf.true_value, threshold_conf.type, threshold_conf.upper);
-
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src.info()->valid_region(), valid_region);
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall,
-                     SmallShapes() * ThresholdDataset(),
-                     shape, threshold_conf)
+template <typename T>
+using CLThresholdFixture = ThresholdValidationFixture<CLTensor, CLAccessor, CLThreshold, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLThresholdFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), datasets::MixedThresholdDataset()),
+                                                                                                         framework::dataset::make("DataType",
+                                                                                                                 DataType::U8)))
 {
-    // Compute function
-    CLTensor dst = compute_threshold(shape, threshold_conf.threshold, threshold_conf.false_value, threshold_conf.true_value, threshold_conf.type, threshold_conf.upper);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_threshold(shape, threshold_conf.threshold, threshold_conf.false_value, threshold_conf.true_value, threshold_conf.type, threshold_conf.upper);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge,
-                     LargeShapes() * ThresholdDataset(),
-                     shape, threshold_conf)
+FIXTURE_DATA_TEST_CASE(RunLarge, CLThresholdFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), datasets::MixedThresholdDataset()),
+                                                                                                       framework::dataset::make("DataType",
+                                                                                                               DataType::U8)))
 {
-    // Compute function
-    CLTensor dst = compute_threshold(shape, threshold_conf.threshold, threshold_conf.false_value, threshold_conf.true_value, threshold_conf.type, threshold_conf.upper);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_threshold(shape, threshold_conf.threshold, threshold_conf.false_value, threshold_conf.true_value, threshold_conf.type, threshold_conf.upper);
-
     // Validate output
-    validate(CLAccessor(dst), ref_dst);
+    validate(CLAccessor(_target), _reference);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CPP/ActivationLayer.cpp b/tests/validation/CPP/ActivationLayer.cpp
new file mode 100644
index 0000000..2243e6f
--- /dev/null
+++ b/tests/validation/CPP/ActivationLayer.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "ActivationLayer.h"
+
+#include "arm_compute/core/Types.h"
+#include "tests/validation/FixedPoint.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type>
+SimpleTensor<T> activation_layer(const SimpleTensor<T> &src, ActivationLayerInfo info)
+{
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const T a(info.a());
+    const T b(info.b());
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        T x = src[i];
+
+        switch(info.activation())
+        {
+            case ActivationLayerInfo::ActivationFunction::ABS:
+                dst[i] = std::abs(x);
+                break;
+            case ActivationLayerInfo::ActivationFunction::LINEAR:
+                dst[i] = a * x + b;
+                break;
+            case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+                dst[i] = static_cast<T>(1) / (static_cast<T>(1) + std::exp(-x));
+                break;
+            case ActivationLayerInfo::ActivationFunction::RELU:
+                dst[i] = std::max<T>(static_cast<T>(0), x);
+                break;
+            case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU:
+                dst[i] = std::min<T>(a, std::max(static_cast<T>(0), x));
+                break;
+            case ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU:
+                dst[i] = std::min<T>(a, std::max<T>(b, x));
+                break;
+            case ActivationLayerInfo::ActivationFunction::LEAKY_RELU:
+                dst[i] = (x > 0) ? x : a * x;
+                break;
+            case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+                dst[i] = std::log(static_cast<T>(1) + std::exp(x));
+                break;
+            case ActivationLayerInfo::ActivationFunction::SQRT:
+                dst[i] = std::sqrt(x);
+                break;
+            case ActivationLayerInfo::ActivationFunction::SQUARE:
+                dst[i] = x * x;
+                break;
+            case ActivationLayerInfo::ActivationFunction::TANH:
+                dst[i] = a * std::tanh(b * x);
+                break;
+            default:
+                ARM_COMPUTE_ERROR("Unsupported activation function");
+        }
+    }
+
+    return dst;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type>
+SimpleTensor<T> activation_layer(const SimpleTensor<T> &src, ActivationLayerInfo info)
+{
+    using namespace fixed_point_arithmetic;
+
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const int            fixed_point_position = src.fixed_point_position();
+    const fixed_point<T> a(info.a(), fixed_point_position);
+    const fixed_point<T> b(info.b(), fixed_point_position);
+    const fixed_point<T> const_0(0, fixed_point_position);
+    const fixed_point<T> const_1(1, fixed_point_position);
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        fixed_point<T> x(src[i], fixed_point_position, true);
+
+        switch(info.activation())
+        {
+            case ActivationLayerInfo::ActivationFunction::ABS:
+                dst[i] = abs(x).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::LINEAR:
+                dst[i] = add(b, mul(a, x)).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+                dst[i] = (const_1 / (const_1 + exp(-x))).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::RELU:
+                dst[i] = max(const_0, x).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU:
+                dst[i] = min(a, max(const_0, x)).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU:
+                dst[i] = min(a, max(b, x)).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::LEAKY_RELU:
+                dst[i] = (x > const_0) ? x.raw() : mul(a, x).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+                dst[i] = log(const_1 + exp(x)).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::SQRT:
+                dst[i] = (const_1 / inv_sqrt(x)).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::SQUARE:
+                dst[i] = mul(x, x).raw();
+                break;
+            case ActivationLayerInfo::ActivationFunction::TANH:
+                dst[i] = mul(a, tanh(mul(b, x))).raw();
+                break;
+            default:
+                ARM_COMPUTE_ERROR("Unsupported activation function");
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> activation_layer(const SimpleTensor<float> &src, ActivationLayerInfo info);
+template SimpleTensor<half> activation_layer(const SimpleTensor<half> &src, ActivationLayerInfo info);
+template SimpleTensor<qint8_t> activation_layer(const SimpleTensor<qint8_t> &src, ActivationLayerInfo info);
+template SimpleTensor<qint16_t> activation_layer(const SimpleTensor<qint16_t> &src, ActivationLayerInfo info);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/ActivationLayer.h
similarity index 67%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/ActivationLayer.h
index bf30db9..09f602f 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/ActivationLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_ACTIVATION_LAYER_H__
+#define __ARM_COMPUTE_TEST_ACTIVATION_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,15 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+SimpleTensor<T> activation_layer(const SimpleTensor<T> &src, ActivationLayerInfo info);
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+SimpleTensor<T> activation_layer(const SimpleTensor<T> &src, ActivationLayerInfo info);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_ACTIVATION_LAYER_H__ */
diff --git a/tests/validation/CPP/ArithmeticAddition.cpp b/tests/validation/CPP/ArithmeticAddition.cpp
new file mode 100644
index 0000000..82dd143
--- /dev/null
+++ b/tests/validation/CPP/ArithmeticAddition.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "ArithmeticAddition.h"
+
+#include "arm_compute/core/Types.h"
+#include "tests/validation/FixedPoint.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> arithmetic_addition(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2, DataType dst_data_type, ConvertPolicy convert_policy)
+{
+    SimpleTensor<T> result(src1.shape(), dst_data_type);
+
+    using intermediate_type = typename common_promoted_signed_type<T>::intermediate_type;
+
+    for(int i = 0; i < src1.num_elements(); ++i)
+    {
+        intermediate_type val = static_cast<intermediate_type>(src1[i]) + static_cast<intermediate_type>(src2[i]);
+        result[i]             = (convert_policy == ConvertPolicy::SATURATE) ? saturate_cast<T>(val) : static_cast<T>(val);
+    }
+
+    return result;
+}
+
+template SimpleTensor<uint8_t> arithmetic_addition(const SimpleTensor<uint8_t> &src1, const SimpleTensor<uint8_t> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+template SimpleTensor<int16_t> arithmetic_addition(const SimpleTensor<int16_t> &src1, const SimpleTensor<int16_t> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+template SimpleTensor<int8_t> arithmetic_addition(const SimpleTensor<int8_t> &src1, const SimpleTensor<int8_t> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+template SimpleTensor<half> arithmetic_addition(const SimpleTensor<half> &src1, const SimpleTensor<half> &src2, DataType dst_data_type,
+                                                ConvertPolicy convert_policy);
+template SimpleTensor<float> arithmetic_addition(const SimpleTensor<float> &src1, const SimpleTensor<float> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/ArithmeticAddition.h
similarity index 73%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/ArithmeticAddition.h
index bf30db9..5902a6f 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/ArithmeticAddition.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_ARITHMETIC_ADDITION_H__
+#define __ARM_COMPUTE_TEST_ARITHMETIC_ADDITION_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> arithmetic_addition(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_ARITHMETIC_ADDITION_H__ */
diff --git a/tests/validation/CPP/ArithmeticSubtraction.cpp b/tests/validation/CPP/ArithmeticSubtraction.cpp
new file mode 100644
index 0000000..80bdb15
--- /dev/null
+++ b/tests/validation/CPP/ArithmeticSubtraction.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "ArithmeticSubtraction.h"
+
+#include "tests/validation/FixedPoint.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> arithmetic_subtraction(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2, DataType dst_data_type, ConvertPolicy convert_policy)
+{
+    SimpleTensor<T> result(src1.shape(), dst_data_type);
+
+    using intermediate_type = typename common_promoted_signed_type<T>::intermediate_type;
+
+    for(int i = 0; i < src1.num_elements(); ++i)
+    {
+        intermediate_type val = static_cast<intermediate_type>(src1[i]) - static_cast<intermediate_type>(src2[i]);
+        result[i]             = (convert_policy == ConvertPolicy::SATURATE) ? saturate_cast<T>(val) : static_cast<T>(val);
+    }
+
+    return result;
+}
+
+template SimpleTensor<uint8_t> arithmetic_subtraction(const SimpleTensor<uint8_t> &src1, const SimpleTensor<uint8_t> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+template SimpleTensor<int16_t> arithmetic_subtraction(const SimpleTensor<int16_t> &src1, const SimpleTensor<int16_t> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+template SimpleTensor<int8_t> arithmetic_subtraction(const SimpleTensor<int8_t> &src1, const SimpleTensor<int8_t> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+template SimpleTensor<half> arithmetic_subtraction(const SimpleTensor<half> &src1, const SimpleTensor<half> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+template SimpleTensor<float> arithmetic_subtraction(const SimpleTensor<float> &src1, const SimpleTensor<float> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/ArithmeticSubtraction.h
similarity index 73%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/ArithmeticSubtraction.h
index bf30db9..18b0d12 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/ArithmeticSubtraction.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_ARITHMETIC_SUBTRACTION_H__
+#define __ARM_COMPUTE_TEST_ARITHMETIC_SUBTRACTION_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> arithmetic_subtraction(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2, DataType dst_data_type, ConvertPolicy convert_policy);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_ARITHMETIC_SUBTRACTION_H__ */
diff --git a/tests/validation/CPP/BatchNormalizationLayer.cpp b/tests/validation/CPP/BatchNormalizationLayer.cpp
new file mode 100644
index 0000000..37e2d55
--- /dev/null
+++ b/tests/validation/CPP/BatchNormalizationLayer.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "BatchNormalizationLayer.h"
+
+#include "tests/validation/FixedPoint.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+// Batch Normalization Layer for fixed point type
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type *>
+SimpleTensor<T> batch_normalization_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &mean, const SimpleTensor<T> &var, const SimpleTensor<T> &beta, const SimpleTensor<T> &gamma, float epsilon,
+                                          int fixed_point_position)
+{
+    SimpleTensor<T> result(src.shape(), src.data_type());
+
+    const auto cols       = static_cast<int>(src.shape()[0]);
+    const auto rows       = static_cast<int>(src.shape()[1]);
+    const auto depth      = static_cast<int>(src.shape()[2]);
+    int        upper_dims = src.shape().total_size() / (cols * rows * depth);
+
+    for(int r = 0; r < upper_dims; ++r)
+    {
+        for(int i = 0; i < depth; ++i)
+        {
+            for(int k = 0; k < rows; ++k)
+            {
+                for(int l = 0; l < cols; ++l)
+                {
+                    const int pos = l + k * cols + i * rows * cols + r * cols * rows * depth;
+
+                    fixed_point_arithmetic::fixed_point<T> src_qs(src[pos], fixed_point_position, true);
+                    fixed_point_arithmetic::fixed_point<T> var_qs(var[i], fixed_point_position, true);
+                    fixed_point_arithmetic::fixed_point<T> mean_qs(mean[i], fixed_point_position, true);
+                    fixed_point_arithmetic::fixed_point<T> beta_qs(beta[i], fixed_point_position, true);
+                    fixed_point_arithmetic::fixed_point<T> gamma_qs(gamma[i], fixed_point_position, true);
+                    fixed_point_arithmetic::fixed_point<T> epsilon_qs(epsilon, fixed_point_position);
+
+                    auto denominator = fixed_point_arithmetic::inv_sqrt(var_qs + epsilon_qs);
+                    auto numerator   = src_qs - mean_qs;
+                    auto x_bar       = numerator * denominator;
+                    x_bar            = beta_qs + x_bar * gamma_qs;
+                    result[pos]      = x_bar.raw();
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+// Batch Normalization Layer for floating point type
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type *>
+SimpleTensor<T> batch_normalization_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &mean, const SimpleTensor<T> &var, const SimpleTensor<T> &beta, const SimpleTensor<T> &gamma, float epsilon,
+                                          int fixed_point_position)
+{
+    ARM_COMPUTE_UNUSED(fixed_point_position);
+
+    SimpleTensor<T> result(src.shape(), src.data_type());
+
+    const auto cols       = static_cast<int>(src.shape()[0]);
+    const auto rows       = static_cast<int>(src.shape()[1]);
+    const auto depth      = static_cast<int>(src.shape()[2]);
+    int        upper_dims = src.shape().total_size() / (cols * rows * depth);
+
+    for(int r = 0; r < upper_dims; ++r)
+    {
+        for(int i = 0; i < depth; ++i)
+        {
+            for(int k = 0; k < rows; ++k)
+            {
+                for(int l = 0; l < cols; ++l)
+                {
+                    const int   pos         = l + k * cols + i * rows * cols + r * cols * rows * depth;
+                    const float denominator = sqrt(var[i] + epsilon);
+                    const float numerator   = src[pos] - mean[i];
+                    const float x_bar       = numerator / denominator;
+                    result[pos]             = beta[i] + x_bar * gamma[i];
+                }
+            }
+        }
+    }
+    return result;
+}
+template SimpleTensor<float> batch_normalization_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &mean, const SimpleTensor<float> &var, const SimpleTensor<float> &beta,
+                                                       const SimpleTensor<float> &gamma, float epsilon, int fixed_point_position);
+template SimpleTensor<int8_t> batch_normalization_layer(const SimpleTensor<int8_t> &src, const SimpleTensor<int8_t> &mean, const SimpleTensor<int8_t> &var, const SimpleTensor<int8_t> &beta,
+                                                        const SimpleTensor<int8_t> &gamma, float epsilon, int fixed_point_position);
+template SimpleTensor<int16_t> batch_normalization_layer(const SimpleTensor<int16_t> &src, const SimpleTensor<int16_t> &mean, const SimpleTensor<int16_t> &var, const SimpleTensor<int16_t> &beta,
+                                                         const SimpleTensor<int16_t> &gamma, float epsilon, int fixed_point_position);
+template SimpleTensor<half> batch_normalization_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &mean, const SimpleTensor<half> &var,
+                                                      const SimpleTensor<half> &beta,
+                                                      const SimpleTensor<half> &gamma, float epsilon, int fixed_point_position);
+
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CPP/BatchNormalizationLayer.h b/tests/validation/CPP/BatchNormalizationLayer.h
new file mode 100644
index 0000000..1a554ad
--- /dev/null
+++ b/tests/validation/CPP/BatchNormalizationLayer.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 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_TEST_BATCH_NORMALIZATION_LAYER_H__
+#define __ARM_COMPUTE_TEST_BATCH_NORMALIZATION_LAYER_H__
+
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
+SimpleTensor<T> batch_normalization_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &mean, const SimpleTensor<T> &var, const SimpleTensor<T> &beta, const SimpleTensor<T> &gamma, float epsilon,
+                                          int fixed_point_position);
+
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type * = nullptr>
+SimpleTensor<T> batch_normalization_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &mean, const SimpleTensor<T> &var, const SimpleTensor<T> &beta, const SimpleTensor<T> &gamma, float epsilon,
+                                          int fixed_point_position);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_TEST_BATCH_NORMALIZATION_LAYER_H__ */
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/BitwiseAnd.cpp
similarity index 73%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/BitwiseAnd.cpp
index 138e056..6fc46b4 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/BitwiseAnd.cpp
@@ -21,10 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "BitwiseAnd.h"
 
 namespace arm_compute
 {
@@ -32,17 +29,23 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
+template <typename T>
+SimpleTensor<T> bitwise_and(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2)
 {
-    CLFixture()
+    SimpleTensor<T> dst(src1.shape(), src1.data_type());
+
+    for(int i = 0; i < src1.num_elements(); ++i)
     {
-        CLScheduler::get().default_init();
+        dst[i] = src1[i] & src2[i];
     }
-};
-} // namespace cl
+
+    return dst;
+}
+
+template SimpleTensor<uint8_t> bitwise_and(const SimpleTensor<uint8_t> &src1, const SimpleTensor<uint8_t> &src2);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/BitwiseAnd.h
similarity index 79%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/BitwiseAnd.h
index 138e056..eba2fd6 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/BitwiseAnd.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_BITWISE_AND_H__
+#define __ARM_COMPUTE_TEST_BITWISE_AND_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> bitwise_and(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_BITWISE_AND_H__ */
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/BitwiseNot.cpp
similarity index 77%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/BitwiseNot.cpp
index 138e056..5a6a13b 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/BitwiseNot.cpp
@@ -21,10 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "BitwiseNot.h"
 
 namespace arm_compute
 {
@@ -32,17 +29,23 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
+template <typename T>
+SimpleTensor<T> bitwise_not(const SimpleTensor<T> &src)
 {
-    CLFixture()
+    SimpleTensor<T> dst(src.shape(), src.data_type());
+
+    for(int i = 0; i < src.num_elements(); ++i)
     {
-        CLScheduler::get().default_init();
+        dst[i] = ~src[i];
     }
-};
-} // namespace cl
+
+    return dst;
+}
+
+template SimpleTensor<uint8_t> bitwise_not(const SimpleTensor<uint8_t> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/BitwiseNot.h
similarity index 81%
rename from tests/validation/CL/CLFixture.h
rename to tests/validation/CPP/BitwiseNot.h
index 138e056..b4206f9 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/BitwiseNot.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_BITWISE_NOT_H__
+#define __ARM_COMPUTE_TEST_BITWISE_NOT_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> bitwise_not(const SimpleTensor<T> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_BITWISE_NOT_H__ */
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/BitwiseOr.cpp
similarity index 73%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/BitwiseOr.cpp
index bf30db9..fc258d5 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/BitwiseOr.cpp
@@ -21,10 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-
-#include "ProgramOptions.h"
+#include "BitwiseOr.h"
 
 namespace arm_compute
 {
@@ -32,14 +29,23 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> bitwise_or(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2)
+{
+    SimpleTensor<T> dst(src1.shape(), src1.data_type());
+
+    for(int i = 0; i < src1.num_elements(); ++i)
+    {
+        dst[i] = src1[i] | src2[i];
+    }
+
+    return dst;
+}
+
+template SimpleTensor<uint8_t> bitwise_or(const SimpleTensor<uint8_t> &src1, const SimpleTensor<uint8_t> &src2);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/BitwiseOr.h
similarity index 79%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/BitwiseOr.h
index 138e056..39158cb 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/BitwiseOr.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_BITWISE_OR_H__
+#define __ARM_COMPUTE_TEST_BITWISE_OR_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> bitwise_or(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_BITWISE_OR_H__ */
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/BitwiseXor.cpp
similarity index 73%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/BitwiseXor.cpp
index 138e056..b8d275d 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/BitwiseXor.cpp
@@ -21,10 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "BitwiseXor.h"
 
 namespace arm_compute
 {
@@ -32,17 +29,23 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
+template <typename T>
+SimpleTensor<T> bitwise_xor(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2)
 {
-    CLFixture()
+    SimpleTensor<T> dst(src1.shape(), src1.data_type());
+
+    for(int i = 0; i < src1.num_elements(); ++i)
     {
-        CLScheduler::get().default_init();
+        dst[i] = src1[i] ^ src2[i];
     }
-};
-} // namespace cl
+
+    return dst;
+}
+
+template SimpleTensor<uint8_t> bitwise_xor(const SimpleTensor<uint8_t> &src1, const SimpleTensor<uint8_t> &src2);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/BitwiseXor.h
similarity index 79%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/BitwiseXor.h
index 138e056..3e7721e 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/BitwiseXor.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_BITWISE_XOR_H__
+#define __ARM_COMPUTE_TEST_BITWISE_XOR_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> bitwise_xor(const SimpleTensor<T> &src1, const SimpleTensor<T> &src2);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_BITWISE_XOR_H__ */
diff --git a/tests/validation/VX/VXHelpers.h b/tests/validation/CPP/Box3x3.cpp
similarity index 60%
rename from tests/validation/VX/VXHelpers.h
rename to tests/validation/CPP/Box3x3.cpp
index c880f84..8d304a8 100644
--- a/tests/validation/VX/VXHelpers.h
+++ b/tests/validation/CPP/Box3x3.cpp
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_VX_HELPERS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_VX_HELPERS_H__
+#include "arm_compute/core/Helpers.h"
 
-#include <VX/vx.h>
+#include "Box3x3.h"
+#include "Utils.h"
 
 namespace arm_compute
 {
@@ -32,34 +32,24 @@
 {
 namespace validation
 {
-namespace vx
+namespace reference
 {
-/** Helper function to get the conversion from Format data type to vx_df_image_e
- *
- * @param[in] format Format type.
- *
- * @return vx_df_image_e of the input type.
- */
-vx_df_image_e get_vximage_format(Format format)
+template <typename T>
+SimpleTensor<T> box3x3(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value)
 {
-    switch(format)
+    SimpleTensor<T> dst(src.shape(), src.data_type());
+    const std::array<T, 9> filter{ { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
+    const float scale = 1.f / static_cast<float>(filter.size());
+    for(int element_idx = 0; element_idx < src.num_elements(); ++element_idx)
     {
-        case Format::U8:
-            return VX_DF_IMAGE_U8;
-        case Format::S16:
-            return VX_DF_IMAGE_S16;
-        case Format::U16:
-            return VX_DF_IMAGE_U16;
-        case Format::S32:
-            return VX_DF_IMAGE_S32;
-        case Format::U32:
-            return VX_DF_IMAGE_U32;
-        default:
-            ARM_COMPUTE_ERROR("NOT SUPPORTED!");
+        const Coordinates id = index2coord(src.shape(), element_idx);
+        apply_2d_spatial_filter(id, src, dst, TensorShape(3U, 3U), filter.data(), scale, border_mode, constant_border_value);
     }
+    return dst;
 }
-} // namespece vx
+
+template SimpleTensor<uint8_t> box3x3(const SimpleTensor<uint8_t> &src, BorderMode border_mode, uint8_t constant_border_value);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif //__ARM_COMPUTE_TEST_VALIDATION_HELPERS_H__
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/Box3x3.h
similarity index 79%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/Box3x3.h
index 138e056..80ac451 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/Box3x3.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_BOX3X3_H__
+#define __ARM_COMPUTE_TEST_BOX3X3_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> box3x3(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_BOX3X3_H__ */
diff --git a/tests/validation/CPP/ConvolutionLayer.cpp b/tests/validation/CPP/ConvolutionLayer.cpp
new file mode 100644
index 0000000..656cd2e
--- /dev/null
+++ b/tests/validation/CPP/ConvolutionLayer.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "ConvolutionLayer.h"
+
+#include "tests/validation/FixedPoint.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+inline bool is_valid_pixel(int i, int min, int max)
+{
+    return (i >= min && i < max);
+}
+
+// 3D convolution for floating point type
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+void convolution3d(const T *in, const T *weights, const T *bias, T *out, int xi, int yi, int width_in, int height_in, int depth_in, int width_weights, int height_weights, int fixed_point_position)
+{
+    ARM_COMPUTE_UNUSED(fixed_point_position);
+
+    const int half_width_weights  = width_weights / 2;
+    const int half_height_weights = height_weights / 2;
+
+    // Reset accumulator
+    T acc(0);
+
+    // Compute a 2D convolution for each IFM and accumulate the result
+    for(int ifm = 0; ifm < depth_in; ++ifm)
+    {
+        // Compute the offset for the input slice
+        const int offset_slice_in = xi + yi * width_in + ifm * width_in * height_in;
+
+        // Compute 2D convolution
+        for(int yk = -half_height_weights; yk <= half_height_weights; ++yk)
+        {
+            for(int xk = -half_width_weights; xk <= half_width_weights; ++xk)
+            {
+                // Check if the pixel is out-of-bound
+                if(is_valid_pixel(xi + xk, 0, width_in) && is_valid_pixel(yi + yk, 0, height_in))
+                {
+                    const int idx = xk + half_width_weights;
+                    const int idy = yk + half_height_weights;
+
+                    const T i_value = in[offset_slice_in + xk + yk * width_in];
+                    const T w_value = weights[idx + idy * width_weights + ifm * width_weights * height_weights];
+
+                    acc += i_value * w_value;
+                }
+            }
+        }
+    }
+
+    // Accumulate the bias and store the result
+    *out = acc + (*bias);
+}
+
+// 3D convolution for fixed point type
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+void convolution3d(const T *in, const T *weights, const T *bias, T *out, int xi, int yi, int width_in, int height_in, int depth_in, int width_weights, int height_weights,
+                   int fixed_point_position)
+{
+    const int half_width_weights  = width_weights / 2;
+    const int half_height_weights = height_weights / 2;
+
+    using namespace fixed_point_arithmetic;
+    using promoted_type = fixed_point_arithmetic::traits::promote_t<T>;
+
+    // Reset accumulator
+    fixed_point<promoted_type> acc(0, fixed_point_position);
+
+    // Compute a 2D convolution for each IFM and accumulate the result
+    for(int ifm = 0; ifm < depth_in; ++ifm)
+    {
+        // Compute the offset for the input slice
+        const int offset_slice_in = xi + yi * width_in + ifm * width_in * height_in;
+
+        // Compute 2D convolution
+        for(int yk = -half_height_weights; yk <= half_height_weights; ++yk)
+        {
+            for(int xk = -half_width_weights; xk <= half_width_weights; ++xk)
+            {
+                // Check if the pixel is out-of-bound
+                if(is_valid_pixel(xi + xk, 0, width_in) && is_valid_pixel(yi + yk, 0, height_in))
+                {
+                    const int idx = xk + half_width_weights;
+                    const int idy = yk + half_height_weights;
+
+                    const fixed_point<promoted_type> i_value(in[offset_slice_in + xk + yk * width_in], fixed_point_position, true);
+                    const fixed_point<promoted_type> w_value(weights[idx + idy * width_weights + ifm * width_weights * height_weights], fixed_point_position, true);
+                    const fixed_point<promoted_type> iw = i_value * w_value;
+                    acc                                 = iw + acc;
+                }
+            }
+        }
+    }
+
+    // Get the bias
+    const fixed_point<promoted_type> b(*bias, fixed_point_position, true);
+
+    // Accumulate the bias and covert back
+    acc = acc + b;
+    fixed_point<T> res(acc);
+    *out = res.raw();
+}
+} // namespace
+
+template <typename T>
+SimpleTensor<T> convolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<T> &bias, const TensorShape &output_shape, const PadStrideInfo &info)
+{
+    // Create reference
+    SimpleTensor<T> dst{ output_shape, src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const int width_in       = src.shape().x();
+    const int height_in      = src.shape().y();
+    const int depth_in       = src.shape().z();
+    const int width_out      = dst.shape().x();
+    const int height_out     = dst.shape().y();
+    const int depth_out      = dst.shape().z();
+    const int width_weights  = weights.shape().x();
+    const int height_weights = weights.shape().y();
+    const int depth_weights  = weights.shape().z();
+    const int pad_xi         = std::min(static_cast<int>(info.pad().first), width_weights / 2);
+    const int pad_yi         = std::min(static_cast<int>(info.pad().second), height_weights / 2);
+    const int start_xi       = width_weights / 2 - pad_xi;
+    const int start_yi       = height_weights / 2 - pad_yi;
+    const int end_xi         = width_in - start_xi;
+    const int end_yi         = height_in - start_yi;
+    const int stride_xi      = info.stride().first;
+    const int stride_yi      = info.stride().second;
+    const int num_batches    = src.shape().total_size() / (width_in * height_in * depth_in);
+
+    for(int r = 0; r < num_batches; ++r)
+    {
+        for(int yi = start_yi; yi < end_yi; yi += stride_yi)
+        {
+            for(int xi = start_xi; xi < end_xi; xi += stride_xi)
+            {
+                for(int ofm = 0; ofm < depth_out; ++ofm)
+                {
+                    // Compute input and output offsets
+                    const int offset_in  = r * width_in * height_in * depth_in;
+                    const int xo         = (xi - start_xi) / stride_xi;
+                    const int yo         = (yi - start_yi) / stride_yi;
+                    const int offset_out = xo + yo * width_out + ofm * width_out * height_out + r * width_out * height_out * depth_out;
+
+                    // Compute 3D convolution
+                    convolution3d(src.data() + offset_in,
+                                  weights.data() + ofm * width_weights * height_weights * depth_weights,
+                                  bias.data() + ofm,
+                                  dst.data() + offset_out,
+                                  xi, yi,
+                                  width_in, height_in, depth_in,
+                                  width_weights, height_weights,
+                                  src.fixed_point_position());
+                }
+            }
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> convolution_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &weights, const SimpleTensor<float> &bias, const TensorShape &output_shape,
+                                               const PadStrideInfo &info);
+template SimpleTensor<half> convolution_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &weights, const SimpleTensor<half> &bias, const TensorShape &output_shape,
+                                              const PadStrideInfo &info);
+template SimpleTensor<qint8_t> convolution_layer(const SimpleTensor<qint8_t> &src, const SimpleTensor<qint8_t> &weights, const SimpleTensor<qint8_t> &bias, const TensorShape &output_shape,
+                                                 const PadStrideInfo &info);
+template SimpleTensor<qint16_t> convolution_layer(const SimpleTensor<qint16_t> &src, const SimpleTensor<qint16_t> &weights, const SimpleTensor<qint16_t> &bias, const TensorShape &output_shape,
+                                                  const PadStrideInfo &info);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/ConvolutionLayer.h
similarity index 72%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/ConvolutionLayer.h
index bf30db9..117e846 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/ConvolutionLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_CONVOLUTION_LAYER_H__
+#define __ARM_COMPUTE_TEST_CONVOLUTION_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> convolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<T> &bias, const TensorShape &output_shape, const PadStrideInfo &info);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_CONVOLUTION_LAYER_H__ */
diff --git a/tests/validation/CPP/DepthConcatenateLayer.cpp b/tests/validation/CPP/DepthConcatenateLayer.cpp
new file mode 100644
index 0000000..9a72484
--- /dev/null
+++ b/tests/validation/CPP/DepthConcatenateLayer.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "DepthConcatenateLayer.h"
+
+#include "tests/validation/FixedPoint.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> depthconcatenate_layer(const std::vector<SimpleTensor<T>> &srcs)
+{
+    // Create reference
+    std::vector<TensorShape> shapes;
+
+    for(const auto &src : srcs)
+    {
+        shapes.emplace_back(src.shape());
+    }
+
+    DataType        dst_type  = srcs.empty() ? DataType::UNKNOWN : srcs[0].data_type();
+    TensorShape     dst_shape = calculate_depth_concatenate_shape(shapes);
+    SimpleTensor<T> dst(dst_shape, dst_type);
+
+    // Compute reference
+    int       depth_offset = 0;
+    const int width_out    = dst.shape().x();
+    const int height_out   = dst.shape().y();
+    const int depth_out    = dst.shape().z();
+    const int out_stride_z = width_out * height_out;
+    const int batches      = dst.shape().total_size_upper(3);
+
+    // Set output tensor to 0
+    std::fill_n(dst.data(), dst.num_elements(), 0);
+
+    for(const auto &src : srcs)
+    {
+        ARM_COMPUTE_ERROR_ON(depth_offset >= depth_out);
+        ARM_COMPUTE_ERROR_ON(batches != static_cast<int>(src.shape().total_size_upper(3)));
+
+        const int width  = src.shape().x();
+        const int height = src.shape().y();
+        const int depth  = src.shape().z();
+        const int x_diff = (width_out - width) / 2;
+        const int y_diff = (height_out - height) / 2;
+
+        const T *src_ptr = src.data();
+
+        for(int b = 0; b < batches; ++b)
+        {
+            const size_t offset_to_first_element = b * out_stride_z * depth_out + depth_offset * out_stride_z + y_diff * width_out + x_diff;
+
+            for(int d = 0; d < depth; ++d)
+            {
+                for(int r = 0; r < height; ++r)
+                {
+                    std::copy(src_ptr, src_ptr + width, dst.data() + offset_to_first_element + d * out_stride_z + r * width_out);
+                    src_ptr += width;
+                }
+            }
+        }
+
+        depth_offset += depth;
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> depthconcatenate_layer(const std::vector<SimpleTensor<float>> &srcs);
+template SimpleTensor<half> depthconcatenate_layer(const std::vector<SimpleTensor<half>> &srcs);
+template SimpleTensor<qint8_t> depthconcatenate_layer(const std::vector<SimpleTensor<qint8_t>> &srcs);
+template SimpleTensor<qint16_t> depthconcatenate_layer(const std::vector<SimpleTensor<qint16_t>> &srcs);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/DepthConcatenateLayer.h
similarity index 77%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/DepthConcatenateLayer.h
index bf30db9..3c486a8 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/DepthConcatenateLayer.h
@@ -21,10 +21,12 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_DEPTHCONCATENATE_LAYER_H__
+#define __ARM_COMPUTE_TEST_DEPTHCONCATENATE_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+
+#include <vector>
 
 namespace arm_compute
 {
@@ -32,14 +34,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> depthconcatenate_layer(const std::vector<SimpleTensor<T>> &srcs);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_DEPTHCONCATENATE_LAYER_H__ */
diff --git a/tests/validation/CPP/DepthConvert.cpp b/tests/validation/CPP/DepthConvert.cpp
new file mode 100644
index 0000000..110174a
--- /dev/null
+++ b/tests/validation/CPP/DepthConvert.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "DepthConvert.h"
+
+#include "tests/validation/FixedPoint.h"
+#include "tests/validation/Helpers.h"
+
+#include "tests/Types.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template < typename T1, typename T2, typename std::enable_if < std::is_integral<T1>::value &&std::is_floating_point<T2>::value, int >::type >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift)
+{
+    ARM_COMPUTE_UNUSED(policy);
+    ARM_COMPUTE_UNUSED(shift);
+
+    using namespace fixed_point_arithmetic;
+    SimpleTensor<T2> result(src.shape(), dt_out);
+
+    const int fixed_point_position = src.fixed_point_position();
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        result[i] = static_cast<float>(fixed_point<T1>(src[i], fixed_point_position, true));
+    }
+
+    return result;
+}
+
+template < typename T1, typename T2, typename std::enable_if < std::is_floating_point<T1>::value &&std::is_integral<T2>::value, int >::type >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift)
+{
+    ARM_COMPUTE_UNUSED(policy);
+    ARM_COMPUTE_UNUSED(shift);
+
+    using namespace fixed_point_arithmetic;
+    SimpleTensor<T2> result(src.shape(), dt_out, 1, src.fixed_point_position());
+
+    const int fixed_point_position = result.fixed_point_position();
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        result[i] = fixed_point<T2>(src[i], fixed_point_position).raw();
+    }
+
+    return result;
+}
+
+template < typename T1, typename T2, typename std::enable_if < std::is_integral<T1>::value &&std::is_integral<T2>::value &&!std::is_same<T1, T2>::value, int >::type >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift)
+{
+    SimpleTensor<T2> result(src.shape(), dt_out);
+
+    // Up-casting
+    if(src.data_type() <= dt_out)
+    {
+        for(int i = 0; i < src.num_elements(); ++i)
+        {
+            result[i] = src[i] << shift;
+        }
+    }
+    // Down-casting
+    else
+    {
+        for(int i = 0; i < src.num_elements(); ++i)
+        {
+            T1 val    = src[i] >> shift;
+            result[i] = (policy == ConvertPolicy::SATURATE) ? saturate_cast<T2>(val) : static_cast<T2>(val);
+        }
+    }
+    return result;
+}
+
+template < typename T1, typename T2, typename std::enable_if < std::is_integral<T1>::value &&std::is_integral<T2>::value &&std::is_same<T1, T2>::value, int >::type >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift)
+{
+    ARM_COMPUTE_UNUSED(policy);
+
+    using namespace fixed_point_arithmetic;
+
+    SimpleTensor<T2> result(src.shape(), dt_out);
+
+    bool is_in_place = (&src == &result);
+
+    const int fixed_point_position_in  = src.fixed_point_position();
+    const int fixed_point_position_out = (is_in_place) ? static_cast<int>(shift) : result.fixed_point_position();
+
+    if(!is_in_place || (fixed_point_position_in != fixed_point_position_out))
+    {
+        for(int i = 0; i < src.num_elements(); ++i)
+        {
+            auto x = fixed_point<T2>(src[i], fixed_point_position_in, true);
+            x.resacle(fixed_point_position_out);
+            result[i] = x.raw();
+        }
+    }
+
+    return result;
+}
+
+template < typename T1, typename T2, typename std::enable_if < std::is_floating_point<T1>::value &&is_floating_point<T2>::value, int >::type >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift)
+{
+    ARM_COMPUTE_UNUSED(policy);
+    ARM_COMPUTE_UNUSED(shift);
+
+    SimpleTensor<T2> result(src.shape(), dt_out);
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        result[i] = static_cast<T2>(src[i]);
+    }
+}
+
+template SimpleTensor<uint16_t> depth_convert(const SimpleTensor<uint8_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<int16_t> depth_convert(const SimpleTensor<uint8_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<int32_t> depth_convert(const SimpleTensor<uint8_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<uint8_t> depth_convert(const SimpleTensor<uint16_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<uint32_t> depth_convert(const SimpleTensor<uint16_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<uint8_t> depth_convert(const SimpleTensor<int16_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<int32_t> depth_convert(const SimpleTensor<int16_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<float> depth_convert(const SimpleTensor<int8_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<float> depth_convert(const SimpleTensor<int16_t> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<int8_t> depth_convert(const SimpleTensor<float> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+template SimpleTensor<int16_t> depth_convert(const SimpleTensor<float> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CPP/DepthConvert.h b/tests/validation/CPP/DepthConvert.h
new file mode 100644
index 0000000..1446bfd
--- /dev/null
+++ b/tests/validation/CPP/DepthConvert.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2017 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_TEST_DEPTH_CONVERT_H__
+#define __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__
+
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template < typename T1, typename T2, typename std::enable_if < std::is_integral<T1>::value &&std::is_floating_point<T2>::value, int >::type = 0 >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+
+template < typename T1, typename T2, typename std::enable_if < std::is_floating_point<T1>::value &&std::is_integral<T2>::value, int >::type = 0 >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+
+template < typename T1, typename T2, typename std::enable_if < std::is_integral<T1>::value &&std::is_integral<T2>::value &&!std::is_same<T1, T2>::value, int >::type = 0 >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+
+template < typename T1, typename T2, typename std::enable_if < std::is_integral<T1>::value &&std::is_integral<T2>::value &&std::is_same<T1, T2>::value, int >::type = 0 >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+
+template < typename T1, typename T2, typename std::enable_if < std::is_floating_point<T1>::value &&is_floating_point<T2>::value, int >::type = 0 >
+SimpleTensor<T2> depth_convert(const SimpleTensor<T1> &src, DataType dt_out, ConvertPolicy policy, uint32_t shift);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_TEST_DEPTH_CONVERT_H__ */
diff --git a/tests/validation/CPP/DepthwiseConvolution.cpp b/tests/validation/CPP/DepthwiseConvolution.cpp
new file mode 100644
index 0000000..ae54494
--- /dev/null
+++ b/tests/validation/CPP/DepthwiseConvolution.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "DepthwiseConvolution.h"
+
+#include "ConvolutionLayer.h"
+#include "Utils.h"
+
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+/** Perform a depthwise convolution
+ *
+ * - Three dimensions tensors
+ * - Third dimention is number of channels
+ * - Depths of input tensor and filter are equals
+ * - Padding, stride and output shape "match"
+ *
+ */
+template <typename T>
+SimpleTensor<T> depthwise_convolution(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const TensorShape &dst_shape, const PadStrideInfo &conv_info)
+{
+    // Create reference
+    SimpleTensor<T> dst{ dst_shape, src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const size_t filter_width  = weights.shape().x();
+    const size_t filter_height = weights.shape().y();
+    const size_t filter_plane  = filter_width * filter_height;
+    const size_t input_width   = src.shape().x();
+    const size_t input_height  = src.shape().y();
+    const size_t input_depth   = src.shape().z();
+    const int    num_batches   = src.shape().total_size() / (input_width * input_height * input_depth);
+
+    const size_t filter_half_width  = filter_width / 2;
+    const size_t filter_half_height = filter_height / 2;
+    const size_t pad_x              = std::min(filter_half_width, static_cast<size_t>(conv_info.pad().first));
+    const size_t pad_y              = std::min(filter_half_height, static_cast<size_t>(conv_info.pad().second));
+    const size_t minimum_x          = -pad_x + filter_half_width;
+    const size_t minimum_y          = -pad_y + filter_half_height;
+
+    int out_pos = 0;
+    for(int r = 0; r < num_batches; ++r)
+    {
+        for(size_t z = 0; z < input_depth; ++z)
+        {
+            for(size_t y = minimum_y; y < input_height - minimum_y; y += conv_info.stride().second)
+            {
+                for(size_t x = minimum_x; x < input_width - minimum_x; x += conv_info.stride().first)
+                {
+                    Coordinates coords(static_cast<int>(x), static_cast<int>(y), static_cast<int>(z), static_cast<int>(r));
+                    size_t      filter_offset = filter_plane * z;
+
+                    T val = 0;
+                    for(int j = y - filter_half_height; j <= static_cast<int>(y + filter_half_height); ++j)
+                    {
+                        for(int i = x - filter_half_width; i <= static_cast<int>(x + filter_half_width); ++i)
+                        {
+                            coords.set(0, i);
+                            coords.set(1, j);
+                            val += *(weights.data() + filter_offset) * tensor_elem_at(src, coords, BorderMode::CONSTANT, 0.f);
+                            ++filter_offset;
+                        }
+                    }
+                    coords.set(0, x);
+                    coords.set(1, y);
+                    dst[out_pos++] = saturate_cast<T>(val);
+                }
+            }
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> depthwise_convolution(const SimpleTensor<float> &src, const SimpleTensor<float> &weights, const TensorShape &dst_shape, const PadStrideInfo &conv_info);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/DepthwiseConvolution.h
similarity index 72%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/DepthwiseConvolution.h
index bf30db9..6be80fc 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/DepthwiseConvolution.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_H__
+#define __ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> depthwise_convolution(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const TensorShape &dst_shape, const PadStrideInfo &conv_info);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_H__ */
diff --git a/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.cpp b/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.cpp
new file mode 100644
index 0000000..3942ecf
--- /dev/null
+++ b/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "DepthwiseConvolution.h"
+
+#include "DepthwiseSeparableConvolutionLayer.h"
+
+#include "ConvolutionLayer.h"
+#include "Utils.h"
+
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+// Depthwise separable convolution layer
+template <typename T>
+SimpleTensor<T> depthwise_separable_convolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &depthwise_weights, const TensorShape &depthwise_out_shape,
+                                                      const SimpleTensor<T> &pointwise_weights,
+                                                      const SimpleTensor<T> &biases, const TensorShape &dst_shape, const PadStrideInfo &depthwise_conv_info, const PadStrideInfo &pointwise_conv_info)
+{
+    // Compute reference
+    SimpleTensor<T> depthwise_out = depthwise_convolution(src, depthwise_weights, depthwise_out_shape, depthwise_conv_info);
+    SimpleTensor<T> dst           = convolution_layer(depthwise_out, pointwise_weights, biases, dst_shape, pointwise_conv_info);
+
+    return dst;
+}
+
+template SimpleTensor<float> depthwise_separable_convolution_layer(const SimpleTensor<float> &in, const SimpleTensor<float> &depthwise_weights, const TensorShape &depthwise_out_shape,
+                                                                   const SimpleTensor<float> &pointwise_weights, const SimpleTensor<float> &biases, const TensorShape &dst_shape, const PadStrideInfo &depthwise_conv_info, const PadStrideInfo &pointwise_conv_info);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.cpp b/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.h
similarity index 61%
rename from tests/validation/ValidationProgramOptions.cpp
rename to tests/validation/CPP/DepthwiseSeparableConvolutionLayer.h
index adb8c5a..71cd013 100644
--- a/tests/validation/ValidationProgramOptions.cpp
+++ b/tests/validation/CPP/DepthwiseSeparableConvolutionLayer.h
@@ -21,16 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "ValidationProgramOptions.h"
+#ifndef __ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_H__
+#define __ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_H__
 
-#include <thread>
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Weffc++"
-#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
-#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
-#include "boost/program_options.hpp"
-#pragma GCC diagnostic pop
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -38,13 +33,14 @@
 {
 namespace validation
 {
-ValidationProgramOptions::ValidationProgramOptions()
+namespace reference
 {
-    boost::program_options::options_description options("Validation options");
-    options.add_options()("runs", boost::program_options::value<unsigned int>()->default_value(1), "Repetitions per test");
-    options.add_options()("threads", boost::program_options::value<unsigned int>()->default_value(std::thread::hardware_concurrency()), "Number of parallel CPU threads");
-    add_options(options);
-}
+template <typename T>
+SimpleTensor<T> depthwise_separable_convolution_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &depthwise_weights, const TensorShape &depthwise_out_shape,
+                                                      const SimpleTensor<T> &pointwise_weights,
+                                                      const SimpleTensor<T> &biases, const TensorShape &dst_shape, const PadStrideInfo &depthwise_conv_info, const PadStrideInfo &pointwise_conv_info);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
+#endif /* __ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_H__ */
diff --git a/tests/validation/CPP/DequantizationLayer.cpp b/tests/validation/CPP/DequantizationLayer.cpp
new file mode 100644
index 0000000..33096a1
--- /dev/null
+++ b/tests/validation/CPP/DequantizationLayer.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "DequantizationLayer.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type>
+SimpleTensor<float> dequantization_layer(const SimpleTensor<T> &src, const SimpleTensor<float> &min_max)
+{
+    // Create reference
+    SimpleTensor<float> dst{ src.shape(), DataType::F32 };
+
+    // Compute reference
+    const int width       = src.shape().x();
+    const int height      = src.shape().y();
+    const int depth       = src.shape().z();
+    const int stride_w    = width * height * depth;
+    const int num_batches = min_max.shape().total_size_upper(1);
+
+    for(int k = 0; k < num_batches; ++k)
+    {
+        const float min     = min_max[k * 2 + 0];
+        const float max     = min_max[k * 2 + 1];
+        const float range   = max - min;
+        const float scaling = range / 255.0f;
+
+        for(int i = 0; i < stride_w; ++i)
+        {
+            dst[i + k * stride_w] = (static_cast<float>(src[i + k * stride_w]) * scaling) + min;
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> dequantization_layer(const SimpleTensor<uint8_t> &src, const SimpleTensor<float> &min_max);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/DequantizationLayer.h
similarity index 72%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/DequantizationLayer.h
index bf30db9..1a8adcf 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/DequantizationLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_DEQUANTIZATION_LAYER_H__
+#define __ARM_COMPUTE_TEST_DEQUANTIZATION_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+SimpleTensor<float> dequantization_layer(const SimpleTensor<T> &src, const SimpleTensor<float> &min_max);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_DEQUANTIZATION_LAYER_H__ */
diff --git a/tests/validation/CPP/FlattenLayer.cpp b/tests/validation/CPP/FlattenLayer.cpp
new file mode 100644
index 0000000..611701d
--- /dev/null
+++ b/tests/validation/CPP/FlattenLayer.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "FlattenLayer.h"
+
+#include "tests/validation/FixedPoint.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> flatten_layer(const SimpleTensor<T> &src)
+{
+    TensorShape shape_flatten(src.shape());
+    shape_flatten.set(0, src.shape()[0] * src.shape()[1] * src.shape()[2]);
+    shape_flatten.remove_dimension(1);
+    shape_flatten.remove_dimension(1);
+    SimpleTensor<T> dst(shape_flatten, src.data_type(), 1, src.fixed_point_position());
+
+    // Note: Since the reference implementation does not use padding bytes, we can copy directly the content of the source tensor
+    std::copy(src.data(), src.data() + src.num_elements(), dst.data());
+
+    return dst;
+}
+
+template SimpleTensor<float> flatten_layer(const SimpleTensor<float> &src);
+template SimpleTensor<half> flatten_layer(const SimpleTensor<half> &src);
+template SimpleTensor<qint8_t> flatten_layer(const SimpleTensor<qint8_t> &src);
+template SimpleTensor<qint16_t> flatten_layer(const SimpleTensor<qint16_t> &src);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/FlattenLayer.h
similarity index 78%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/FlattenLayer.h
index 138e056..b1286fe 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/FlattenLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_FLATTEN_LAYER_H__
+#define __ARM_COMPUTE_TEST_FLATTEN_LAYER_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,17 +33,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> flatten_layer(const SimpleTensor<T> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_FLATTEN_LAYER_H__ */
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/Floor.cpp
similarity index 72%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/Floor.cpp
index 138e056..1c73944 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/Floor.cpp
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#include "Floor.h"
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/validation/Helpers.h"
+
+#include <cmath>
 
 namespace arm_compute
 {
@@ -32,17 +33,25 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
+template <typename T>
+SimpleTensor<T> floor_layer(const SimpleTensor<T> &src)
 {
-    CLFixture()
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type() };
+
+    // Compute reference
+    for(int i = 0; i < src.num_elements(); ++i)
     {
-        CLScheduler::get().default_init();
+        dst[i] = std::floor(src[i]);
     }
-};
-} // namespace cl
+
+    return dst;
+}
+
+template SimpleTensor<float> floor_layer(const SimpleTensor<float> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/Floor.h
similarity index 80%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/Floor.h
index 138e056..d95ee30 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/Floor.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_FLOOR_H__
+#define __ARM_COMPUTE_TEST_FLOOR_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,17 +33,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> floor_layer(const SimpleTensor<T> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_FLOOR_H__ */
diff --git a/tests/validation/CPP/FullyConnectedLayer.cpp b/tests/validation/CPP/FullyConnectedLayer.cpp
new file mode 100644
index 0000000..2b32c4b
--- /dev/null
+++ b/tests/validation/CPP/FullyConnectedLayer.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "FullyConnectedLayer.h"
+
+#include "arm_compute/core/Types.h"
+#include "tests/validation/FixedPoint.h"
+
+#include <numeric>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+// Vector matrix multiply for floating point
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+void vector_matrix_multiply(const T *src, const T *weights, const T *bias, T *dst, int cols_weights, int rows_weights, uint8_t fixed_point_position)
+{
+    ARM_COMPUTE_UNUSED(fixed_point_position);
+
+    for(int y = 0; y < rows_weights; ++y)
+    {
+        dst[y] = std::inner_product(src, src + cols_weights, weights, static_cast<T>(0)) + bias[y];
+        weights += cols_weights;
+    }
+}
+
+// Vector matrix multiply for fixed point type
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+void vector_matrix_multiply(const T *src, const T *weights, const T *bias, T *dst, int cols_weights, int rows_weights, uint8_t fixed_point_position)
+{
+    using namespace fixed_point_arithmetic;
+    using promoted_type = fixed_point_arithmetic::traits::promote_t<T>;
+
+    for(int y = 0; y < rows_weights; ++y)
+    {
+        // Reset accumulator
+        fixed_point<promoted_type> acc(0, fixed_point_position);
+
+        for(int x = 0; x < cols_weights; ++x)
+        {
+            const fixed_point<promoted_type> i_value(src[x], fixed_point_position, true);
+            const fixed_point<promoted_type> w_value(weights[x], fixed_point_position, true);
+            acc = acc + i_value * w_value;
+        }
+
+        // Get the bias
+        const fixed_point<T> b(bias[y], fixed_point_position, true);
+
+        // Convert back and accumulate the bias
+        fixed_point<T> res(acc);
+        res = res + b;
+
+        // Store the result
+        dst[y] = res.raw();
+
+        weights += cols_weights;
+    }
+}
+} // namespace
+
+template <typename T>
+SimpleTensor<T> fully_connected_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<T> &bias, const TensorShape &dst_shape)
+{
+    // Create reference
+    SimpleTensor<T> dst{ TensorShape{ dst_shape }, src.data_type(), 1, src.fixed_point_position() };
+
+    // Sanity checks
+    const int          num_batch_dimensions = std::max(0, static_cast<int>(dst_shape.num_dimensions()) - 1);
+    const int          num_input_dimensions = src.shape().num_dimensions() - num_batch_dimensions;
+    const unsigned int linear_input_size    = src.shape().total_size_lower(num_input_dimensions);
+
+    ARM_COMPUTE_UNUSED(num_batch_dimensions);
+    ARM_COMPUTE_UNUSED(num_input_dimensions);
+    ARM_COMPUTE_UNUSED(linear_input_size);
+    ARM_COMPUTE_ERROR_ON(weights.shape().x() != linear_input_size);
+    ARM_COMPUTE_ERROR_ON(weights.shape().y() != bias.shape().x());
+    ARM_COMPUTE_ERROR_ON(weights.shape().y() != dst.shape().x());
+
+    // Compute reference
+    const int cols_weights = weights.shape().x();
+    const int rows_weights = weights.shape().y();
+    const int num_batches  = dst_shape.total_size_upper(1);
+
+    for(int k = 0; k < num_batches; ++k)
+    {
+        vector_matrix_multiply<T>(src.data() + k * cols_weights,
+                                  weights.data(),
+                                  bias.data(),
+                                  dst.data() + k * rows_weights,
+                                  cols_weights,
+                                  rows_weights,
+                                  src.fixed_point_position());
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> fully_connected_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &weights, const SimpleTensor<float> &bias, const TensorShape &dst_shape);
+template SimpleTensor<half> fully_connected_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &weights, const SimpleTensor<half> &bias, const TensorShape &dst_shape);
+template SimpleTensor<qint8_t> fully_connected_layer(const SimpleTensor<qint8_t> &src, const SimpleTensor<qint8_t> &weights, const SimpleTensor<qint8_t> &bias, const TensorShape &dst_shape);
+template SimpleTensor<qint16_t> fully_connected_layer(const SimpleTensor<qint16_t> &src, const SimpleTensor<qint16_t> &weights, const SimpleTensor<qint16_t> &bias, const TensorShape &dst_shape);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/FullyConnectedLayer.h
similarity index 73%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/FullyConnectedLayer.h
index bf30db9..05c570a 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/FullyConnectedLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_FULLY_CONNECTED_LAYER_H__
+#define __ARM_COMPUTE_TEST_FULLY_CONNECTED_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> fully_connected_layer(const SimpleTensor<T> &src, const SimpleTensor<T> &weights, const SimpleTensor<T> &bias, const TensorShape &dst_shape);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_FULLY_CONNECTED_LAYER_H__ */
diff --git a/tests/validation/CPP/GEMM.cpp b/tests/validation/CPP/GEMM.cpp
new file mode 100644
index 0000000..77d025e
--- /dev/null
+++ b/tests/validation/CPP/GEMM.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "GEMM.h"
+
+#include "arm_compute/core/Types.h"
+#include "tests/validation/FixedPoint.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type>
+SimpleTensor<T> gemm(const SimpleTensor<T> &a, const SimpleTensor<T> &b, const SimpleTensor<T> &c, float alpha, float beta)
+{
+    // Create reference
+    SimpleTensor<T> dst{ c.shape(), c.data_type(), 1, c.fixed_point_position() };
+
+    // Compute reference
+    const int M = dst.shape().y();
+    const int N = dst.shape().x();
+    const int K = a.shape().x();
+
+    for(int row = 0; row < M; ++row)
+    {
+        for(int col = 0; col < N; ++col)
+        {
+            T acc(0);
+
+            for(int k = 0; k < K; ++k)
+            {
+                acc += a[row * K + k] * b[k * N + col];
+            }
+
+            // Finalize the result: alpha * A * B + beta * C
+            dst[col + row * N] = alpha * acc + beta * c[col + row * N];
+        }
+    }
+
+    return dst;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type>
+SimpleTensor<T> gemm(const SimpleTensor<T> &a, const SimpleTensor<T> &b, const SimpleTensor<T> &c, float alpha, float beta)
+{
+    using namespace fixed_point_arithmetic;
+
+    // Create reference
+    SimpleTensor<T> dst{ c.shape(), c.data_type(), 1, c.fixed_point_position() };
+
+    // Compute reference
+    using promoted_type = fixed_point_arithmetic::traits::promote_t<T>;
+
+    const int M                    = dst.shape().y();
+    const int N                    = dst.shape().x();
+    const int K                    = a.shape().x();
+    const int fixed_point_position = a.fixed_point_position();
+
+    const fixed_point<T> alpha_q(alpha, fixed_point_position);
+    const fixed_point<T> beta_q(beta, fixed_point_position);
+
+    for(int row = 0; row < M; ++row)
+    {
+        for(int col = 0; col < N; ++col)
+        {
+            fixed_point<promoted_type> acc_q(0, fixed_point_position);
+
+            for(int k = 0; k < K; ++k)
+            {
+                const fixed_point<promoted_type> a0_q(a[row * K + k], fixed_point_position, true);
+                const fixed_point<promoted_type> b0_q(b[k * N + col], fixed_point_position, true);
+
+                acc_q = acc_q + (a0_q * b0_q);
+            }
+
+            // Finalize the result: alpha * A * B + beta * C
+            const fixed_point<T> c0_q(c[col + row * N], fixed_point_position, true);
+
+            fixed_point<T> res_q(acc_q);
+            res_q = alpha_q * res_q;
+            res_q = res_q + (beta_q * c0_q);
+
+            // Store the result
+            dst[col + row * N] = res_q.raw();
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> gemm(const SimpleTensor<float> &a, const SimpleTensor<float> &b, const SimpleTensor<float> &c, float alpha, float beta);
+template SimpleTensor<half> gemm(const SimpleTensor<half> &a, const SimpleTensor<half> &b, const SimpleTensor<half> &c, float alpha, float beta);
+template SimpleTensor<qint8_t> gemm(const SimpleTensor<qint8_t> &a, const SimpleTensor<qint8_t> &b, const SimpleTensor<qint8_t> &c, float alpha, float beta);
+template SimpleTensor<qint16_t> gemm(const SimpleTensor<qint16_t> &a, const SimpleTensor<qint16_t> &b, const SimpleTensor<qint16_t> &c, float alpha, float beta);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/GEMM.h
similarity index 65%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/GEMM.h
index bf30db9..cda792b 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/GEMM.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_GEMM_H__
+#define __ARM_COMPUTE_TEST_GEMM_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,15 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+SimpleTensor<T> gemm(const SimpleTensor<T> &a, const SimpleTensor<T> &b, const SimpleTensor<T> &c, float alpha, float beta);
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+SimpleTensor<T> gemm(const SimpleTensor<T> &a, const SimpleTensor<T> &b, const SimpleTensor<T> &c, float alpha, float beta);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_GEMM_H__ */
diff --git a/tests/validation/VX/VXHelpers.h b/tests/validation/CPP/Gaussian3x3.cpp
similarity index 60%
copy from tests/validation/VX/VXHelpers.h
copy to tests/validation/CPP/Gaussian3x3.cpp
index c880f84..c71eade 100644
--- a/tests/validation/VX/VXHelpers.h
+++ b/tests/validation/CPP/Gaussian3x3.cpp
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_VX_HELPERS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_VX_HELPERS_H__
+#include "arm_compute/core/Helpers.h"
 
-#include <VX/vx.h>
+#include "Gaussian3x3.h"
+#include "Utils.h"
 
 namespace arm_compute
 {
@@ -32,34 +32,24 @@
 {
 namespace validation
 {
-namespace vx
+namespace reference
 {
-/** Helper function to get the conversion from Format data type to vx_df_image_e
- *
- * @param[in] format Format type.
- *
- * @return vx_df_image_e of the input type.
- */
-vx_df_image_e get_vximage_format(Format format)
+template <typename T>
+SimpleTensor<T> gaussian3x3(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value)
 {
-    switch(format)
+    SimpleTensor<T> dst(src.shape(), src.data_type());
+    const std::array<T, 9> filter{ { 1, 2, 1, 2, 4, 2, 1, 2, 1 } };
+    const float scale = 1.f / 16.f;
+    for(int element_idx = 0; element_idx < src.num_elements(); ++element_idx)
     {
-        case Format::U8:
-            return VX_DF_IMAGE_U8;
-        case Format::S16:
-            return VX_DF_IMAGE_S16;
-        case Format::U16:
-            return VX_DF_IMAGE_U16;
-        case Format::S32:
-            return VX_DF_IMAGE_S32;
-        case Format::U32:
-            return VX_DF_IMAGE_U32;
-        default:
-            ARM_COMPUTE_ERROR("NOT SUPPORTED!");
+        const Coordinates id = index2coord(src.shape(), element_idx);
+        apply_2d_spatial_filter(id, src, dst, TensorShape(3U, 3U), filter.data(), scale, border_mode, constant_border_value);
     }
+    return dst;
 }
-} // namespece vx
+
+template SimpleTensor<uint8_t> gaussian3x3(const SimpleTensor<uint8_t> &src, BorderMode border_mode, uint8_t constant_border_value);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif //__ARM_COMPUTE_TEST_VALIDATION_HELPERS_H__
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/Gaussian3x3.h
similarity index 78%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/Gaussian3x3.h
index 138e056..85a7acd 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/Gaussian3x3.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_GAUSSIAN3X3_H__
+#define __ARM_COMPUTE_TEST_GAUSSIAN3X3_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> gaussian3x3(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_GAUSSIAN3X3_H__ */
diff --git a/tests/validation/CPP/Gaussian5x5.cpp b/tests/validation/CPP/Gaussian5x5.cpp
new file mode 100644
index 0000000..55bb287
--- /dev/null
+++ b/tests/validation/CPP/Gaussian5x5.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Helpers.h"
+
+#include "Gaussian5x5.h"
+#include "Utils.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> gaussian5x5(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value)
+{
+    SimpleTensor<T> dst(src.shape(), src.data_type());
+    const std::array<T, 25> filter{ {
+            1, 4, 6, 4, 1,
+            4, 16, 24, 16, 4,
+            6, 24, 36, 24, 6,
+            4, 16, 24, 16, 4,
+            1, 4, 6, 4, 1
+        } };
+    const float scale = 1.f / 256.f;
+    for(int element_idx = 0; element_idx < src.num_elements(); ++element_idx)
+    {
+        const Coordinates id = index2coord(src.shape(), element_idx);
+        apply_2d_spatial_filter(id, src, dst, TensorShape(5U, 5U), filter.data(), scale, border_mode, constant_border_value);
+    }
+    return dst;
+}
+
+template SimpleTensor<uint8_t> gaussian5x5(const SimpleTensor<uint8_t> &src, BorderMode border_mode, uint8_t constant_border_value);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/Gaussian5x5.h
similarity index 78%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/Gaussian5x5.h
index 138e056..df981c7 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/Gaussian5x5.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_GAUSSIAN5X5_H__
+#define __ARM_COMPUTE_TEST_GAUSSIAN5X5_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> gaussian5x5(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_GAUSSIAN5X5_H__ */
diff --git a/tests/validation/CPP/HarrisCornerDetector.cpp b/tests/validation/CPP/HarrisCornerDetector.cpp
new file mode 100644
index 0000000..3babfee
--- /dev/null
+++ b/tests/validation/CPP/HarrisCornerDetector.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "HarrisCornerDetector.h"
+
+#include "Utils.h"
+#include "tests/validation/CPP/NonMaximaSuppression.h"
+#include "tests/validation/CPP/Sobel.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+template <typename T>
+std::tuple<SimpleTensor<T>, SimpleTensor<T>, float> compute_sobel(const SimpleTensor<uint8_t> &src, int gradient_size, int block_size, BorderMode border_mode, uint8_t constant_border_value)
+{
+    SimpleTensor<T> grad_x;
+    SimpleTensor<T> grad_y;
+    float           norm_factor = 0.f;
+
+    std::tie(grad_x, grad_y) = sobel<T>(src, gradient_size, border_mode, constant_border_value);
+
+    switch(gradient_size)
+    {
+        case 3:
+            norm_factor = 1.f / (4 * 255 * block_size);
+            break;
+        case 5:
+            norm_factor = 1.f / (16 * 255 * block_size);
+            break;
+        case 7:
+            norm_factor = 1.f / (64 * 255 * block_size);
+            break;
+        default:
+            ARM_COMPUTE_ERROR("Gradient size not supported.");
+    }
+
+    return std::make_tuple(grad_x, grad_y, norm_factor);
+}
+
+template <typename T, typename U>
+std::vector<KeyPoint> harris_corner_detector_impl(const SimpleTensor<U> &src, float threshold, float min_dist, float sensitivity, int gradient_size, int block_size, BorderMode border_mode,
+                                                  U constant_border_value)
+{
+    ARM_COMPUTE_ERROR_ON(block_size != 3 && block_size != 5 && block_size != 7);
+
+    SimpleTensor<T> grad_x;
+    SimpleTensor<T> grad_y;
+    float           norm_factor = 0.f;
+
+    // Sobel
+    std::tie(grad_x, grad_y, norm_factor) = compute_sobel<T>(src, gradient_size, block_size, border_mode, constant_border_value);
+
+    SimpleTensor<float> scores(src.shape(), DataType::F32);
+    ValidRegion         scores_region = shape_to_valid_region(scores.shape(), border_mode == BorderMode::UNDEFINED, BorderSize(gradient_size / 2 + block_size / 2));
+
+    // Calculate scores
+    for(int i = 0; i < scores.num_elements(); ++i)
+    {
+        Coordinates src_coord = index2coord(src.shape(), i);
+        Coordinates block_top_left{ src_coord.x() - block_size / 2, src_coord.y() - block_size / 2 };
+        Coordinates block_bottom_right{ src_coord.x() + block_size / 2, src_coord.y() + block_size / 2 };
+
+        if(!is_in_valid_region(scores_region, src_coord))
+        {
+            scores[i] = 0.f;
+            continue;
+        }
+
+        float Gx2 = 0.f;
+        float Gy2 = 0.f;
+        float Gxy = 0.f;
+
+        // Calculate Gx^2, Gy^2 and Gxy within the given window
+        for(int y = src_coord.y() - block_size / 2; y <= src_coord.y() + block_size / 2; ++y)
+        {
+            for(int x = src_coord.x() - block_size / 2; x <= src_coord.x() + block_size / 2; ++x)
+            {
+                Coordinates block_coord(x, y);
+
+                const float norm_x = tensor_elem_at(grad_x, block_coord, border_mode, static_cast<T>(constant_border_value)) * norm_factor;
+                const float norm_y = tensor_elem_at(grad_y, block_coord, border_mode, static_cast<T>(constant_border_value)) * norm_factor;
+
+                Gx2 += std::pow(norm_x, 2);
+                Gy2 += std::pow(norm_y, 2);
+                Gxy += norm_x * norm_y;
+            }
+        }
+
+        const float trace2   = std::pow(Gx2 + Gy2, 2);
+        const float det      = Gx2 * Gy2 - std::pow(Gxy, 2);
+        const float response = det - sensitivity * trace2;
+
+        if(response > threshold)
+        {
+            scores[i] = response;
+        }
+        else
+        {
+            scores[i] = 0.f;
+        }
+    }
+
+    // Suppress non-maxima candidates
+    SimpleTensor<float> suppressed_scores        = non_maxima_suppression(scores, border_mode != BorderMode::UNDEFINED ? BorderMode::CONSTANT : BorderMode::UNDEFINED, 0.f);
+    ValidRegion         suppressed_scores_region = shape_to_valid_region(suppressed_scores.shape(), border_mode == BorderMode::UNDEFINED, BorderSize(gradient_size / 2 + block_size / 2 + 1));
+
+    // Create vector of candidate corners
+    std::vector<KeyPoint> corner_candidates;
+
+    for(int i = 0; i < suppressed_scores.num_elements(); ++i)
+    {
+        Coordinates coord = index2coord(suppressed_scores.shape(), i);
+
+        if(is_in_valid_region(suppressed_scores_region, coord) && suppressed_scores[i] > 0.f)
+        {
+            KeyPoint corner;
+            corner.x               = coord.x();
+            corner.y               = coord.y();
+            corner.tracking_status = 1;
+            corner.strength        = suppressed_scores[i];
+            corner.scale           = 0.f;
+            corner.orientation     = 0.f;
+            corner.error           = 0.f;
+
+            corner_candidates.emplace_back(corner);
+        }
+    }
+
+    // Sort descending by strength
+    std::sort(corner_candidates.begin(), corner_candidates.end(), [](const KeyPoint & a, const KeyPoint & b)
+    {
+        return a.strength > b.strength;
+    });
+
+    std::vector<KeyPoint> corners;
+    corners.reserve(corner_candidates.size());
+
+    // Only add corner if there is no stronger within min_dist
+    for(const KeyPoint &point : corner_candidates)
+    {
+        const auto strongest = std::find_if(corners.begin(), corners.end(), [&](const KeyPoint & other)
+        {
+            return std::sqrt((std::pow(point.x - other.x, 2) + std::pow(point.y - other.y, 2))) < min_dist;
+        });
+
+        if(strongest == corners.end())
+        {
+            corners.emplace_back(point);
+        }
+    }
+
+    corners.shrink_to_fit();
+
+    return corners;
+}
+} // namespace
+
+template <typename T>
+std::vector<KeyPoint> harris_corner_detector(const SimpleTensor<T> &src, float threshold, float min_dist, float sensitivity, int gradient_size, int block_size, BorderMode border_mode,
+                                             T constant_border_value)
+{
+    if(gradient_size < 7)
+    {
+        return harris_corner_detector_impl<int16_t>(src, threshold, min_dist, sensitivity, gradient_size, block_size, border_mode, constant_border_value);
+    }
+    else
+    {
+        return harris_corner_detector_impl<int32_t>(src, threshold, min_dist, sensitivity, gradient_size, block_size, border_mode, constant_border_value);
+    }
+}
+
+template std::vector<KeyPoint> harris_corner_detector(const SimpleTensor<uint8_t> &src, float threshold, float min_dist, float sensitivity, int gradient_size, int block_size, BorderMode border_mode,
+                                                      uint8_t constant_border_value);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/HarrisCornerDetector.h
similarity index 68%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/HarrisCornerDetector.h
index bf30db9..042e857 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/HarrisCornerDetector.h
@@ -21,10 +21,13 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_HARRIS_CORNER_DETECTOR_H__
+#define __ARM_COMPUTE_TEST_HARRIS_CORNER_DETECTOR_H__
 
-#include "ProgramOptions.h"
+#include "arm_compute/core/Types.h"
+#include "tests/SimpleTensor.h"
+
+#include <vector>
 
 namespace arm_compute
 {
@@ -32,14 +35,13 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+std::vector<KeyPoint> harris_corner_detector(const SimpleTensor<T> &src, float threshold, float min_dist, float sensitivity, int gradient_size, int block_size, BorderMode border_mode,
+                                             T constant_border_value = 0);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_HARRIS_CORNER_DETECTOR_H__ */
diff --git a/tests/validation/CPP/IntegralImage.cpp b/tests/validation/CPP/IntegralImage.cpp
new file mode 100644
index 0000000..8d07e99
--- /dev/null
+++ b/tests/validation/CPP/IntegralImage.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "IntegralImage.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<uint32_t> integral_image(const SimpleTensor<T> &src)
+{
+    SimpleTensor<uint32_t> dst(src.shape(), DataType::U32);
+
+    // Length of dimensions
+    const size_t width  = src.shape().x();
+    const size_t height = src.shape().y();
+    const size_t depth  = src.shape().total_size_upper(2);
+
+    const size_t image_size = width * height;
+
+    for(size_t z = 0; z < depth; ++z)
+    {
+        size_t current_image = z * image_size;
+
+        //First element of each image
+        dst[current_image] = src[current_image];
+
+        // First row of each image (add only pixel on the left)
+        for(size_t x = 1; x < width; ++x)
+        {
+            dst[current_image + x] = static_cast<uint32_t>(src[current_image + x]) + dst[current_image + x - 1];
+        }
+
+        // Subsequent rows
+        for(size_t y = 1; y < height; ++y)
+        {
+            size_t current_row = current_image + (width * y);
+
+            // First element of each row (add only pixel up)
+            dst[current_row] = static_cast<uint32_t>(src[current_row]) + dst[current_row - width];
+
+            // Following row elements
+            for(size_t x = 1; x < width; ++x)
+            {
+                size_t current_pixel = current_row + x;
+
+                // out = in + up(out) + left(out) - up_left(out)
+                dst[current_pixel] = static_cast<uint32_t>(src[current_pixel]) + dst[current_pixel - 1]
+                                     + dst[current_pixel - width] - dst[current_pixel - width - 1];
+            }
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<uint32_t> integral_image(const SimpleTensor<uint8_t> &src);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/IntegralImage.h
similarity index 80%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/IntegralImage.h
index 138e056..c766aae 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/IntegralImage.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_INTEGRAL_IMAGE_H__
+#define __ARM_COMPUTE_TEST_INTEGRAL_IMAGE_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<uint32_t> integral_image(const SimpleTensor<T> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_INTEGRAL_IMAGE_H__ */
diff --git a/tests/validation/CPP/L2Normalize.cpp b/tests/validation/CPP/L2Normalize.cpp
new file mode 100644
index 0000000..4fb4d57
--- /dev/null
+++ b/tests/validation/CPP/L2Normalize.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "L2Normalize.h"
+#include "ReductionOperation.h"
+
+#include "tests/validation/Helpers.h"
+
+#include <algorithm>
+#include <cmath>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+TensorShape get_output_shape(TensorShape shape, unsigned int axis)
+{
+    TensorShape output_shape(shape);
+    output_shape.set(axis, 1);
+    return output_shape;
+}
+} // namespace
+
+template <typename T>
+SimpleTensor<T> l2_normalize(const SimpleTensor<T> &src, unsigned int axis, float epsilon)
+{
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type() };
+
+    // Reduce across given axis
+    SimpleTensor<T> sum = reduction_operation(src, get_output_shape(src.shape(), axis), axis, ReductionOperation::SUM_SQUARE);
+
+    // Compute reference
+    const int elems      = src.shape()[axis];
+    const int upper_dims = src.shape().total_size_upper(axis + 1);
+
+    for(int du = 0; du < upper_dims; ++du)
+    {
+        if(axis == 0)
+        {
+            const T *src_row_ptr         = src.data() + du * elems;
+            T       *dst_row_ptr         = dst.data() + du * elems;
+            const T  normalization_value = std::sqrt(std::max(sum[du], epsilon));
+            std::transform(src_row_ptr, src_row_ptr + elems, dst_row_ptr, [normalization_value](T val)
+            {
+                return val / normalization_value;
+            });
+        }
+        else
+        {
+            ARM_COMPUTE_ERROR("Unsupported normalization axis");
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> l2_normalize(const SimpleTensor<float> &src, unsigned int axis, float epsilon);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/L2Normalize.h
similarity index 77%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/L2Normalize.h
index bf30db9..1db3ae6 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/L2Normalize.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_L2NORMALIZE_H__
+#define __ARM_COMPUTE_TEST_L2NORMALIZE_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> l2_normalize(const SimpleTensor<T> &src, unsigned int axis, float epsilon);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_L2NORMALIZE_H__ */
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/MeanStdDev.cpp
similarity index 64%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/MeanStdDev.cpp
index 138e056..4a39b13 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/MeanStdDev.cpp
@@ -21,10 +21,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "MeanStdDev.h"
 
 namespace arm_compute
 {
@@ -32,17 +29,29 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
+template <typename T>
+std::pair<float, float> mean_and_standard_deviation(const SimpleTensor<T> &in)
 {
-    CLFixture()
+    const int num_elements = in.num_elements();
+
+    // Calculate mean
+    float mean = std::accumulate(in.data(), in.data() + num_elements, 0.f) / num_elements;
+
+    // Calculate standard deviation
+    float std_dev = std::accumulate(in.data(), in.data() + num_elements, 0.f, [&mean](float a, float b)
     {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+        return a + (mean - b) * (mean - b);
+    });
+
+    std_dev = std::sqrt(std_dev / num_elements);
+
+    return std::make_pair(mean, std_dev);
+}
+
+template std::pair<float, float> mean_and_standard_deviation(const SimpleTensor<uint8_t> &in);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/MeanStdDev.h
similarity index 79%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/MeanStdDev.h
index 138e056..6b89ae0 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/MeanStdDev.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_STD_MEAN_DEV_H__
+#define __ARM_COMPUTE_TEST_STD_MEAN_DEV_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+std::pair<float, float> mean_and_standard_deviation(const SimpleTensor<T> &in);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_STD_MEAN_DEV_H__ */
diff --git a/tests/validation/CPP/MinMaxLocation.cpp b/tests/validation/CPP/MinMaxLocation.cpp
new file mode 100644
index 0000000..427adeb
--- /dev/null
+++ b/tests/validation/CPP/MinMaxLocation.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017 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 src 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 src 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. src NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER src AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR src CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "MinMaxLocation.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+void compute_min_max(const SimpleTensor<T> &src, T &min, T &max)
+{
+    // Set min and max to first pixel
+    min = src[0];
+    max = src[0];
+
+    ARM_COMPUTE_ERROR_ON(src.num_elements() == 0);
+
+    // Look for min and max values
+    for(int i = 1; i < src.num_elements(); ++i)
+    {
+        if(src[i] < min)
+        {
+            min = src[i];
+        }
+        if(src[i] > max)
+        {
+            max = src[i];
+        }
+    }
+}
+
+template <typename T>
+MinMaxLocationValues<T> min_max_location(const SimpleTensor<T> &src)
+{
+    MinMaxLocationValues<T> dst;
+
+    const size_t width = src.shape().x();
+
+    compute_min_max<T>(src, dst.min, dst.max);
+
+    Coordinates2D coord{ 0, 0 };
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        coord.x = static_cast<int32_t>(i % width);
+        coord.y = static_cast<int32_t>(i / width);
+
+        if(src[i] == dst.min)
+        {
+            dst.min_loc.push_back(coord);
+        }
+        if(src[i] == dst.max)
+        {
+            dst.max_loc.push_back(coord);
+        }
+    }
+
+    return dst;
+}
+
+template MinMaxLocationValues<uint8_t> min_max_location(const SimpleTensor<uint8_t> &src);
+template MinMaxLocationValues<int16_t> min_max_location(const SimpleTensor<int16_t> &src);
+template MinMaxLocationValues<float> min_max_location(const SimpleTensor<float> &src);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/MinMaxLocation.h
similarity index 78%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/MinMaxLocation.h
index 138e056..ebaf90b 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/MinMaxLocation.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_MIN_MAX_LOCATION_H__
+#define __ARM_COMPUTE_TEST_MIN_MAX_LOCATION_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
+#include "tests/Types.h"
 
 namespace arm_compute
 {
@@ -32,17 +33,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+MinMaxLocationValues<T> min_max_location(const SimpleTensor<T> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_MIN_MAX_LOCATION_H__ */
diff --git a/tests/validation/CPP/NonLinearFilter.cpp b/tests/validation/CPP/NonLinearFilter.cpp
new file mode 100644
index 0000000..8669c9c
--- /dev/null
+++ b/tests/validation/CPP/NonLinearFilter.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2017 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 src 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 src 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. src NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER src AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * dst OF OR src CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "NonLinearFilter.h"
+#include "Utils.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> non_linear_filter(const SimpleTensor<T> &src, NonLinearFilterFunction function, unsigned int mask_size, MatrixPattern pattern, const uint8_t *mask, BorderMode border_mode,
+                                  uint8_t constant_border_value)
+{
+    SimpleTensor<T> dst(src.shape(), src.data_type());
+
+    ARM_COMPUTE_ERROR_ON(pattern == MatrixPattern::OTHER && mask == nullptr);
+    ARM_COMPUTE_UNUSED(pattern);
+
+    using intermediate_type = typename common_promoted_signed_type<T>::intermediate_type;
+
+    const int                      sq_mask_size   = mask_size * mask_size;
+    const int                      half_mask_size = mask_size / 2;
+    std::vector<intermediate_type> vals(sq_mask_size);
+    intermediate_type              current_value = 0;
+
+    const ValidRegion valid_region = shape_to_valid_region(src.shape(), border_mode == BorderMode::UNDEFINED, BorderSize(half_mask_size));
+
+    for(int element_idx = 0, count = 0, index = 0; element_idx < src.num_elements(); ++element_idx, count = 0, index = 0)
+    {
+        Coordinates id = index2coord(src.shape(), element_idx);
+        if(is_in_valid_region(valid_region, id))
+        {
+            int idx = id.x();
+            int idy = id.y();
+            for(int y = idy - half_mask_size; y <= idy + half_mask_size; ++y)
+            {
+                for(int x = idx - half_mask_size; x <= idx + half_mask_size; ++x, ++index)
+                {
+                    id.set(0, x);
+                    id.set(1, y);
+                    current_value = tensor_elem_at(src, id, border_mode, constant_border_value);
+
+                    if(mask[index] == 255)
+                    {
+                        vals[count] = static_cast<intermediate_type>(current_value);
+                        ++count;
+                    }
+                }
+            }
+            std::sort(vals.begin(), vals.begin() + count);
+
+            ARM_COMPUTE_ERROR_ON(count == 0);
+
+            switch(function)
+            {
+                case NonLinearFilterFunction::MIN:
+                    dst[element_idx] = saturate_cast<T>(vals[0]);
+                    break;
+                case NonLinearFilterFunction::MAX:
+                    dst[element_idx] = saturate_cast<T>(vals[count - 1]);
+                    break;
+                case NonLinearFilterFunction::MEDIAN:
+                    dst[element_idx] = saturate_cast<T>(vals[count / 2]);
+                    break;
+                default:
+                    ARM_COMPUTE_ERROR("Unsupported NonLinearFilter function.");
+            }
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<uint8_t> non_linear_filter(const SimpleTensor<uint8_t> &src, NonLinearFilterFunction function, unsigned int mask_size, MatrixPattern pattern, const uint8_t *mask,
+                                                 BorderMode border_mode, uint8_t constant_border_value);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/NonLinearFilter.h
similarity index 72%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/NonLinearFilter.h
index bf30db9..1df47c8 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/NonLinearFilter.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_BITWISE_NOT_H__
+#define __ARM_COMPUTE_TEST_BITWISE_NOT_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,14 +32,13 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> non_linear_filter(const SimpleTensor<T> &src, NonLinearFilterFunction function, unsigned int mask_size, MatrixPattern pattern, const uint8_t *mask, BorderMode border_mode,
+                                  uint8_t constant_border_value);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_BITWISE_NOT_H__ */
diff --git a/tests/validation/CPP/NonMaximaSuppression.cpp b/tests/validation/CPP/NonMaximaSuppression.cpp
new file mode 100644
index 0000000..eab5cec
--- /dev/null
+++ b/tests/validation/CPP/NonMaximaSuppression.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "NonMaximaSuppression.h"
+
+#include "Utils.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> non_maxima_suppression(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value)
+{
+    constexpr int   block_size = 3;
+    SimpleTensor<T> dst(src.shape(), src.data_type(), src.num_channels());
+    ValidRegion     valid_region = shape_to_valid_region(src.shape(), border_mode == BorderMode::UNDEFINED, BorderSize(block_size / 2));
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        Coordinates coord = index2coord(src.shape(), i);
+        int         x     = coord.x();
+        int         y     = coord.y();
+
+        if(!is_in_valid_region(valid_region, coord))
+        {
+            continue;
+        }
+
+        if(src[i] >= tensor_elem_at(src, Coordinates(x - 1, y - 1), border_mode, constant_border_value) && src[i] >= tensor_elem_at(src, Coordinates(x, y - 1), border_mode, constant_border_value)
+           && src[i] >= tensor_elem_at(src, Coordinates(x + 1, y - 1), border_mode, constant_border_value) && src[i] >= tensor_elem_at(src, Coordinates(x - 1, y), border_mode, constant_border_value)
+           && src[i] > tensor_elem_at(src, Coordinates(x + 1, y), border_mode, constant_border_value) && src[i] > tensor_elem_at(src, Coordinates(x - 1, y + 1), border_mode, constant_border_value)
+           && src[i] > tensor_elem_at(src, Coordinates(x, y + 1), border_mode, constant_border_value) && src[i] > tensor_elem_at(src, Coordinates(x + 1, y + 1), border_mode, constant_border_value))
+        {
+            dst[i] = src[i];
+        }
+        else
+        {
+            dst[i] = T(0);
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> non_maxima_suppression(const SimpleTensor<float> &src, BorderMode border_mode, float constant_border_value);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/NonMaximaSuppression.h
similarity index 74%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/NonMaximaSuppression.h
index bf30db9..2086abf 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/NonMaximaSuppression.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_NON_MAXIMA_SUPPRESSION_H__
+#define __ARM_COMPUTE_TEST_NON_MAXIMA_SUPPRESSION_H__
 
-#include "ProgramOptions.h"
+#include "arm_compute/core/Types.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> non_maxima_suppression(const SimpleTensor<T> &src, BorderMode border_mode, T constant_border_value = 0);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_NON_MAXIMA_SUPPRESSION_H__ */
diff --git a/tests/validation/CPP/NormalizationLayer.cpp b/tests/validation/CPP/NormalizationLayer.cpp
new file mode 100644
index 0000000..226af96
--- /dev/null
+++ b/tests/validation/CPP/NormalizationLayer.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "NormalizationLayer.h"
+
+#include "arm_compute/core/Types.h"
+#include "tests/validation/FixedPoint.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type>
+SimpleTensor<T> normalization_layer(const SimpleTensor<T> &src, NormalizationLayerInfo info)
+{
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const uint32_t norm_size = info.norm_size();
+    NormType       type      = info.type();
+    float          beta      = info.beta();
+    uint32_t       kappa     = info.kappa();
+
+    const int cols       = src.shape()[0];
+    const int rows       = src.shape()[1];
+    const int depth      = src.shape()[2];
+    int       upper_dims = src.shape().total_size() / (cols * rows);
+
+    float coeff       = info.scale_coeff();
+    int   radius_cols = norm_size / 2;
+
+    // IN_MAP_1D and CROSS_MAP normalize over a single axis only
+    int radius_rows = (NormType::IN_MAP_2D == type) ? norm_size / 2 : 0;
+
+    if(type == NormType::CROSS_MAP)
+    {
+        // Remove also depth from upper dimensions since it is the dimension we
+        // want to use for normalization
+        upper_dims /= depth;
+
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int i = 0; i < rows; ++i)
+            {
+                for(int k = 0; k < cols; ++k)
+                {
+                    for(int l = 0; l < depth; ++l)
+                    {
+                        float accumulated_scale = 0.f;
+
+                        for(int j = -radius_cols; j <= radius_cols; ++j)
+                        {
+                            const int z = l + j;
+
+                            if(z >= 0 && z < depth)
+                            {
+                                const T value = src[k + i * cols + z * rows * cols + r * cols * rows * depth];
+                                accumulated_scale += value * value;
+                            }
+                        }
+
+                        dst[k + i * cols + l * rows * cols + r * cols * rows * depth] = kappa + accumulated_scale * coeff;
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int i = 0; i < rows; ++i)
+            {
+                for(int k = 0; k < cols; ++k)
+                {
+                    float accumulated_scale = 0.f;
+
+                    for(int j = -radius_rows; j <= radius_rows; ++j)
+                    {
+                        const int y = i + j;
+                        for(int l = -radius_cols; l <= radius_cols; ++l)
+                        {
+                            const int x = k + l;
+
+                            if((x >= 0 && y >= 0) && (x < cols && y < rows))
+                            {
+                                const T value = src[x + y * cols + r * cols * rows];
+                                accumulated_scale += value * value;
+                            }
+                        }
+                    }
+
+                    dst[k + i * cols + r * cols * rows] = kappa + accumulated_scale * coeff;
+                }
+            }
+        }
+    }
+
+    if(beta == 1.f)
+    {
+        for(int i = 0; i < dst.num_elements(); ++i)
+        {
+            dst[i] = src[i] / dst[i];
+        }
+    }
+    else if(beta == 0.5f)
+    {
+        for(int i = 0; i < dst.num_elements(); ++i)
+        {
+            dst[i] = src[i] / std::sqrt(dst[i]);
+        }
+    }
+    else
+    {
+        for(int i = 0; i < dst.num_elements(); ++i)
+        {
+            dst[i] = src[i] * std::exp(std::log(dst[i]) * -beta);
+        }
+    }
+
+    return dst;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type>
+SimpleTensor<T> normalization_layer(const SimpleTensor<T> &src, NormalizationLayerInfo info)
+{
+    using namespace fixed_point_arithmetic;
+
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const int fixed_point_position = src.fixed_point_position();
+
+    const uint32_t norm_size = info.norm_size();
+    NormType       type      = info.type();
+    fixed_point<T> beta(info.beta(), fixed_point_position);
+    fixed_point<T> kappa(info.kappa(), fixed_point_position);
+
+    const int cols       = src.shape()[0];
+    const int rows       = src.shape()[1];
+    const int depth      = src.shape()[2];
+    int       upper_dims = src.shape().total_size() / (cols * rows);
+
+    fixed_point<T> coeff(info.scale_coeff(), fixed_point_position);
+    int            radius_cols = norm_size / 2;
+
+    // IN_MAP_1D and CROSS_MAP normalize over a single axis only
+    int radius_rows = (NormType::IN_MAP_2D == type) ? norm_size / 2 : 0;
+
+    if(type == NormType::CROSS_MAP)
+    {
+        // Remove also depth from upper dimensions since it is the dimension we
+        // want to use for normalization
+        upper_dims /= depth;
+
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int i = 0; i < rows; ++i)
+            {
+                for(int k = 0; k < cols; ++k)
+                {
+                    for(int l = 0; l < depth; ++l)
+                    {
+                        fixed_point<T> accumulated_scale(0.f, fixed_point_position);
+
+                        for(int j = -radius_cols; j <= radius_cols; ++j)
+                        {
+                            const int z = l + j;
+
+                            if(z >= 0 && z < depth)
+                            {
+                                const T              value = src[k + i * cols + z * rows * cols + r * cols * rows * depth];
+                                const fixed_point<T> fp_value(value, fixed_point_position, true);
+                                accumulated_scale = add(accumulated_scale, mul(fp_value, fp_value));
+                            }
+                        }
+
+                        accumulated_scale                                             = add(kappa, mul(accumulated_scale, coeff));
+                        dst[k + i * cols + l * rows * cols + r * cols * rows * depth] = accumulated_scale.raw();
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int i = 0; i < rows; ++i)
+            {
+                for(int k = 0; k < cols; ++k)
+                {
+                    fixed_point<T> accumulated_scale(0.f, fixed_point_position);
+
+                    for(int j = -radius_rows; j <= radius_rows; ++j)
+                    {
+                        const int y = i + j;
+
+                        for(int l = -radius_cols; l <= radius_cols; ++l)
+                        {
+                            const int x = k + l;
+
+                            if((x >= 0 && y >= 0) && (x < cols && y < rows))
+                            {
+                                const T              value = src[x + y * cols + r * cols * rows];
+                                const fixed_point<T> fp_value(value, fixed_point_position, true);
+                                accumulated_scale = add(accumulated_scale, mul(fp_value, fp_value));
+                            }
+                        }
+                    }
+
+                    accumulated_scale                   = add(kappa, mul(accumulated_scale, coeff));
+                    dst[k + i * cols + r * cols * rows] = accumulated_scale.raw();
+                }
+            }
+        }
+    }
+
+    if(info.beta() == 1.f)
+    {
+        for(int i = 0; i < dst.num_elements(); ++i)
+        {
+            fixed_point<T> res = div(fixed_point<T>(src[i], fixed_point_position, true), fixed_point<T>(dst[i], fixed_point_position, true));
+            dst[i]             = res.raw();
+        }
+    }
+    else
+    {
+        const fixed_point<T> beta(info.beta(), fixed_point_position);
+
+        for(int i = 0; i < dst.num_elements(); ++i)
+        {
+            fixed_point<T> res = pow(fixed_point<T>(dst[i], fixed_point_position, true), beta);
+            res                = div(fixed_point<T>(src[i], fixed_point_position, true), res);
+            dst[i]             = res.raw();
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> normalization_layer(const SimpleTensor<float> &src, NormalizationLayerInfo info);
+template SimpleTensor<half> normalization_layer(const SimpleTensor<half> &src, NormalizationLayerInfo info);
+template SimpleTensor<qint8_t> normalization_layer(const SimpleTensor<qint8_t> &src, NormalizationLayerInfo info);
+template SimpleTensor<qint16_t> normalization_layer(const SimpleTensor<qint16_t> &src, NormalizationLayerInfo info);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/NormalizationLayer.h
similarity index 66%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/NormalizationLayer.h
index bf30db9..3f624ff 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/NormalizationLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_NORMALIZATION_LAYER_H__
+#define __ARM_COMPUTE_TEST_NORMALIZATION_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,15 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+SimpleTensor<T> normalization_layer(const SimpleTensor<T> &src, NormalizationLayerInfo info);
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+SimpleTensor<T> normalization_layer(const SimpleTensor<T> &src, NormalizationLayerInfo info);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_NORMALIZATION_LAYER_H__ */
diff --git a/tests/validation/CPP/PoolingLayer.cpp b/tests/validation/CPP/PoolingLayer.cpp
new file mode 100644
index 0000000..85a8343
--- /dev/null
+++ b/tests/validation/CPP/PoolingLayer.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "PoolingLayer.h"
+
+#include "arm_compute/core/Types.h"
+#include "tests/validation/FixedPoint.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+TensorShape calculate_output_shape(TensorShape shape, PoolingLayerInfo info)
+{
+    TensorShape dst_shape = shape;
+    const std::pair<unsigned int, unsigned int> scaled_dims = arm_compute::scaled_dimensions(shape.x(),
+                                                                                             shape.y(),
+                                                                                             info.pool_size(),
+                                                                                             info.pool_size(),
+                                                                                             info.pad_stride_info());
+    dst_shape.set(0, scaled_dims.first);
+    dst_shape.set(1, scaled_dims.second);
+
+    return dst_shape;
+}
+} // namespace
+
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type>
+SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, PoolingLayerInfo info)
+{
+    const int   pool_size     = info.pool_size();
+    PoolingType type          = info.pool_type();
+    int         pool_stride_x = info.pad_stride_info().stride().first;
+    int         pool_stride_y = info.pad_stride_info().stride().second;
+    int         pad_x         = info.pad_stride_info().pad().first;
+    int         pad_y         = info.pad_stride_info().pad().second;
+
+    const auto w_src      = static_cast<int>(src.shape()[0]);
+    const auto h_src      = static_cast<int>(src.shape()[1]);
+    const int  upper_dims = src.shape().total_size() / (w_src * h_src);
+
+    // Create reference
+    SimpleTensor<T> dst{ calculate_output_shape(src.shape(), info), src.data_type(), 1, src.fixed_point_position() };
+
+    const auto w_dst = static_cast<int>(dst.shape()[0]);
+    const auto h_dst = static_cast<int>(dst.shape()[1]);
+
+    if(type == PoolingType::MAX)
+    {
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int h = 0; h < h_dst; ++h)
+            {
+                for(int w = 0; w < w_dst; ++w)
+                {
+                    int wstart = w * pool_stride_x - pad_x;
+                    int hstart = h * pool_stride_y - pad_y;
+                    int wend   = std::min(wstart + pool_size, w_src);
+                    int hend   = std::min(hstart + pool_size, h_src);
+                    wstart     = std::max(wstart, 0);
+                    hstart     = std::max(hstart, 0);
+
+                    T max_val = std::numeric_limits<T>::lowest();
+                    for(int y = hstart; y < hend; ++y)
+                    {
+                        for(int x = wstart; x < wend; ++x)
+                        {
+                            const T val = src[r * h_src * w_src + y * w_src + x];
+                            if(val > max_val)
+                            {
+                                max_val = val;
+                            }
+                        }
+                    }
+
+                    dst[r * h_dst * w_dst + h * w_dst + w] = max_val;
+                }
+            }
+        }
+    }
+    else // Average or l2 pooling
+    {
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int h = 0; h < h_dst; ++h)
+            {
+                for(int w = 0; w < w_dst; ++w)
+                {
+                    T   avg_val(0);
+                    int wstart = w * pool_stride_x - pad_x;
+                    int hstart = h * pool_stride_y - pad_y;
+                    int wend   = std::min(wstart + pool_size, w_src + pad_x);
+                    int hend   = std::min(hstart + pool_size, h_src + pad_y);
+                    int pool   = (hend - hstart) * (wend - wstart);
+                    wstart     = std::max(wstart, 0);
+                    hstart     = std::max(hstart, 0);
+                    wend       = std::min(wend, w_src);
+                    hend       = std::min(hend, h_src);
+
+                    if(type == PoolingType::AVG)
+                    {
+                        for(int y = hstart; y < hend; ++y)
+                        {
+                            for(int x = wstart; x < wend; ++x)
+                            {
+                                avg_val += src[r * h_src * w_src + y * w_src + x];
+                            }
+                        }
+                        dst[r * h_dst * w_dst + h * w_dst + w] = avg_val / pool;
+                    }
+                    else
+                    {
+                        for(int y = hstart; y < hend; ++y)
+                        {
+                            for(int x = wstart; x < wend; ++x)
+                            {
+                                const T val = src[r * h_src * w_src + y * w_src + x];
+                                avg_val += val * val;
+                            }
+                        }
+                        dst[r * h_dst * w_dst + h * w_dst + w] = std::sqrt(avg_val / pool);
+                    }
+                }
+            }
+        }
+    }
+
+    return dst;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type>
+SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, PoolingLayerInfo info)
+{
+    const int   pool_size     = info.pool_size();
+    PoolingType type          = info.pool_type();
+    int         pool_stride_x = info.pad_stride_info().stride().first;
+    int         pool_stride_y = info.pad_stride_info().stride().second;
+    int         pad_x         = info.pad_stride_info().pad().first;
+    int         pad_y         = info.pad_stride_info().pad().second;
+
+    const auto w_src      = static_cast<int>(src.shape()[0]);
+    const auto h_src      = static_cast<int>(src.shape()[1]);
+    const int  upper_dims = src.shape().total_size() / (w_src * h_src);
+
+    // Create reference
+    SimpleTensor<T> dst{ calculate_output_shape(src.shape(), info), src.data_type(), 1, src.fixed_point_position() };
+
+    const auto w_dst = static_cast<int>(dst.shape()[0]);
+    const auto h_dst = static_cast<int>(dst.shape()[1]);
+
+    if(type == PoolingType::MAX)
+    {
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int h = 0; h < h_dst; ++h)
+            {
+                for(int w = 0; w < w_dst; ++w)
+                {
+                    int wstart = w * pool_stride_x - pad_x;
+                    int hstart = h * pool_stride_y - pad_y;
+                    int wend   = std::min(wstart + pool_size, w_src);
+                    int hend   = std::min(hstart + pool_size, h_src);
+                    wstart     = std::max(wstart, 0);
+                    hstart     = std::max(hstart, 0);
+
+                    T max_val = std::numeric_limits<T>::lowest();
+                    for(int y = hstart; y < hend; ++y)
+                    {
+                        for(int x = wstart; x < wend; ++x)
+                        {
+                            const T val = src[r * h_src * w_src + y * w_src + x];
+                            if(val > max_val)
+                            {
+                                max_val = val;
+                            }
+                        }
+                    }
+
+                    dst[r * h_dst * w_dst + h * w_dst + w] = max_val;
+                }
+            }
+        }
+    }
+    else // Average or l2 pooling
+    {
+        for(int r = 0; r < upper_dims; ++r)
+        {
+            for(int h = 0; h < h_dst; ++h)
+            {
+                for(int w = 0; w < w_dst; ++w)
+                {
+                    int wstart = w * pool_stride_x - pad_x;
+                    int hstart = h * pool_stride_y - pad_y;
+                    int wend   = std::min(wstart + pool_size, w_src + pad_x);
+                    int hend   = std::min(hstart + pool_size, h_src + pad_y);
+                    int pool   = (hend - hstart) * (wend - wstart);
+                    wstart     = std::max(wstart, 0);
+                    hstart     = std::max(hstart, 0);
+                    wend       = std::min(wend, w_src);
+                    hend       = std::min(hend, h_src);
+
+                    using namespace fixed_point_arithmetic;
+
+                    const int            fixed_point_position = src.fixed_point_position();
+                    const fixed_point<T> const_1(1, fixed_point_position);
+                    const fixed_point<T> invpool_fp(1.f / static_cast<float>(pool), fixed_point_position);
+                    fixed_point<T>       avg_val(0, fixed_point_position, true);
+
+                    if(type == PoolingType::AVG)
+                    {
+                        for(int y = hstart; y < hend; ++y)
+                        {
+                            for(int x = wstart; x < wend; ++x)
+                            {
+                                const fixed_point<T> in_fp(src[r * h_src * w_src + y * w_src + x], fixed_point_position, true);
+                                avg_val = add(avg_val, in_fp);
+                            }
+                        }
+                        dst[r * h_dst * w_dst + h * w_dst + w] = mul(avg_val, invpool_fp).raw();
+                    }
+                    else
+                    {
+                        for(int y = hstart; y < hend; ++y)
+                        {
+                            for(int x = wstart; x < wend; ++x)
+                            {
+                                const fixed_point<T> in_fp(src[r * h_src * w_src + y * w_src + x], fixed_point_position, true);
+                                avg_val = add(avg_val, mul(in_fp, in_fp));
+                            }
+                        }
+                        auto res                               = div(const_1, (inv_sqrt(mul(avg_val, invpool_fp))));
+                        dst[r * h_dst * w_dst + h * w_dst + w] = res.raw();
+                    }
+                }
+            }
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> pooling_layer(const SimpleTensor<float> &src, PoolingLayerInfo info);
+template SimpleTensor<half> pooling_layer(const SimpleTensor<half> &src, PoolingLayerInfo info);
+template SimpleTensor<qint8_t> pooling_layer(const SimpleTensor<qint8_t> &src, PoolingLayerInfo info);
+template SimpleTensor<qint16_t> pooling_layer(const SimpleTensor<qint16_t> &src, PoolingLayerInfo info);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/PoolingLayer.h
similarity index 67%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/PoolingLayer.h
index bf30db9..334054a 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/PoolingLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_POOLING_LAYER_H__
+#define __ARM_COMPUTE_TEST_POOLING_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,15 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, PoolingLayerInfo info);
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+SimpleTensor<T> pooling_layer(const SimpleTensor<T> &src, PoolingLayerInfo info);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_POOLING_LAYER_H__ */
diff --git a/tests/validation/CPP/QuantizationLayer.cpp b/tests/validation/CPP/QuantizationLayer.cpp
new file mode 100644
index 0000000..d7ce490
--- /dev/null
+++ b/tests/validation/CPP/QuantizationLayer.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "QuantizationLayer.h"
+
+#include <cmath>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type>
+SimpleTensor<uint8_t> quantization_layer(const SimpleTensor<T> &src)
+{
+    // Create reference
+    SimpleTensor<uint8_t> dst{ src.shape(), DataType::U8 };
+
+    const int width       = src.shape().x();
+    const int height      = src.shape().y();
+    const int depth       = src.shape().z();
+    const int stride_w    = width * height * depth;
+    const int num_batches = src.shape().total_size_upper(3);
+
+    for(int k = 0; k < num_batches; ++k)
+    {
+        // Compute min and max of the 3D tensor
+        float min = src[k * stride_w];
+        float max = src[k * stride_w];
+
+        // Look for min and max values
+        for(int i = 1; i < stride_w; ++i)
+        {
+            float val = src[i + k * stride_w];
+            min       = std::min(min, val);
+            max       = std::max(max, val);
+        }
+
+        // Saturate the result in case min = max
+        if(min == max)
+        {
+            min = 0.0f;
+            max = 1.0f;
+        }
+
+        const float range = max - min;
+
+        for(int i = 0; i < stride_w; ++i)
+        {
+            // map values to range [0.0, 1.0]
+            float       val        = src[i + k * stride_w];
+            const float normalized = (val - min) / range;
+            dst[i + k * stride_w]  = static_cast<uint8_t>(std::min(255.0f, normalized * 256.0f));
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<uint8_t> quantization_layer(const SimpleTensor<float> &src);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/QuantizationLayer.h
similarity index 74%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/QuantizationLayer.h
index bf30db9..7c5572c 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/QuantizationLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_QUANTIZATION_LAYER_H__
+#define __ARM_COMPUTE_TEST_QUANTIZATION_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+SimpleTensor<uint8_t> quantization_layer(const SimpleTensor<T> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_QUANTIZATION_LAYER_H__ */
diff --git a/tests/validation/CPP/ReductionOperation.cpp b/tests/validation/CPP/ReductionOperation.cpp
new file mode 100644
index 0000000..acfcc09
--- /dev/null
+++ b/tests/validation/CPP/ReductionOperation.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "ReductionOperation.h"
+
+#include "tests/validation/Helpers.h"
+
+#include <algorithm>
+#include <cmath>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+template <typename T>
+struct square
+{
+    T operator()(const T &lhs, const T &rhs) const
+    {
+        return (lhs + rhs * rhs);
+    }
+};
+
+template <typename T>
+T reduce_operation(T *ptr, int reduce_elements, ReductionOperation op)
+{
+    switch(op)
+    {
+        case ReductionOperation::SUM_SQUARE:
+            return std::accumulate(ptr, ptr + reduce_elements, 0.f, square<T>());
+        default:
+            ARM_COMPUTE_ERROR("Unsupported reduction operation");
+    }
+}
+} // namespace
+
+template <typename T>
+SimpleTensor<T> reduction_operation(const SimpleTensor<T> &src, const TensorShape &dst_shape, unsigned int axis, ReductionOperation op)
+{
+    // Create reference
+    SimpleTensor<T> dst{ dst_shape, src.data_type() };
+
+    // Compute reference
+    const int reduce_elems = src.shape()[axis];
+    const int upper_dims   = src.shape().total_size_upper(axis + 1);
+
+    for(int du = 0; du < upper_dims; ++du)
+    {
+        if(axis == 0)
+        {
+            const T *src_row_ptr = src.data() + du * reduce_elems;
+            dst[du]              = reduce_operation(src_row_ptr, reduce_elems, op);
+        }
+        else
+        {
+            ARM_COMPUTE_ERROR("Unsupported reduction axis");
+        }
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> reduction_operation(const SimpleTensor<float> &src, const TensorShape &dst_shape, unsigned int axis, ReductionOperation op);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/ReductionOperation.h
similarity index 75%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/ReductionOperation.h
index bf30db9..6da6436 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/ReductionOperation.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_REDUCTION_OPERATION_H__
+#define __ARM_COMPUTE_TEST_REDUCTION_OPERATION_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> reduction_operation(const SimpleTensor<T> &src, const TensorShape &dst_shape, unsigned int axis, ReductionOperation op);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_FLOOR_H__ */
diff --git a/tests/validation/CPP/ReshapeLayer.cpp b/tests/validation/CPP/ReshapeLayer.cpp
new file mode 100644
index 0000000..42f06e4
--- /dev/null
+++ b/tests/validation/CPP/ReshapeLayer.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "ReshapeLayer.h"
+
+#include "arm_compute/core/Types.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> reshape_layer(const SimpleTensor<T> &src, const TensorShape &output_shape)
+{
+    ARM_COMPUTE_ERROR_ON(src.shape().total_size() != output_shape.total_size());
+
+    SimpleTensor<T> dst(output_shape, src.data_type());
+    std::copy_n(src.data(), src.num_elements(), dst.data());
+    return dst;
+}
+
+template SimpleTensor<uint8_t> reshape_layer(const SimpleTensor<uint8_t> &src, const TensorShape &output_shape);
+template SimpleTensor<int8_t> reshape_layer(const SimpleTensor<int8_t> &src, const TensorShape &output_shape);
+template SimpleTensor<uint16_t> reshape_layer(const SimpleTensor<uint16_t> &src, const TensorShape &output_shape);
+template SimpleTensor<int16_t> reshape_layer(const SimpleTensor<int16_t> &src, const TensorShape &output_shape);
+template SimpleTensor<uint32_t> reshape_layer(const SimpleTensor<uint32_t> &src, const TensorShape &output_shape);
+template SimpleTensor<int32_t> reshape_layer(const SimpleTensor<int32_t> &src, const TensorShape &output_shape);
+template SimpleTensor<half> reshape_layer(const SimpleTensor<half> &src, const TensorShape &output_shape);
+template SimpleTensor<float> reshape_layer(const SimpleTensor<float> &src, const TensorShape &output_shape);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/ReshapeLayer.h
similarity index 79%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/ReshapeLayer.h
index 138e056..fc6c716 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/ReshapeLayer.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_RESHAPE_LAYER_H__
+#define __ARM_COMPUTE_TEST_RESHAPE_LAYER_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> reshape_layer(const SimpleTensor<T> &src, const TensorShape &output_shape);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_RESHAPE_LAYER_H__ */
diff --git a/tests/validation/CPP/Scale.cpp b/tests/validation/CPP/Scale.cpp
new file mode 100644
index 0000000..74489aa
--- /dev/null
+++ b/tests/validation/CPP/Scale.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include "arm_compute/core/Helpers.h"
+
+#include "Scale.h"
+#include "Utils.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> scale(const SimpleTensor<T> &in, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, T constant_border_value)
+{
+    TensorShape shape_scaled(in.shape());
+    shape_scaled.set(0, in.shape()[0] * scale_x);
+    shape_scaled.set(1, in.shape()[1] * scale_y);
+    SimpleTensor<T> out(shape_scaled, in.data_type());
+
+    // Compute the ratio between source width/height and destination width/height
+    const auto wr = static_cast<float>(in.shape()[0]) / static_cast<float>(out.shape()[0]);
+    const auto hr = static_cast<float>(in.shape()[1]) / static_cast<float>(out.shape()[1]);
+
+    const auto width  = static_cast<int>(in.shape().x());
+    const auto height = static_cast<int>(in.shape().y());
+
+    // Area interpolation behaves as Nearest Neighbour in case of up-sampling
+    if(policy == InterpolationPolicy::AREA && wr <= 1.f && hr <= 1.f)
+    {
+        policy = InterpolationPolicy::NEAREST_NEIGHBOR;
+    }
+
+    for(int element_idx = 0, count = 0; element_idx < out.num_elements(); ++element_idx, ++count)
+    {
+        Coordinates id    = index2coord(out.shape(), element_idx);
+        int         idx   = id.x();
+        int         idy   = id.y();
+        float       x_src = (idx + 0.5f) * wr - 0.5f;
+        float       y_src = (idy + 0.5f) * hr - 0.5f;
+
+        switch(policy)
+        {
+            case InterpolationPolicy::NEAREST_NEIGHBOR:
+            {
+                //Calculate the source coords without -0.5f is equivalent to round the x_scr/y_src coords
+                x_src = (idx + 0.5f) * wr;
+                y_src = (idy + 0.5f) * hr;
+                id.set(0, x_src);
+                id.set(1, y_src);
+
+                // If coordinates in range of tensor's width or height
+                if(x_src >= -1 || y_src >= -1 || x_src <= width || y_src <= height)
+                {
+                    out[element_idx] = tensor_elem_at(in, id, border_mode, constant_border_value);
+                }
+                else
+                {
+                    if(border_mode == BorderMode::CONSTANT)
+                    {
+                        out[element_idx] = constant_border_value;
+                    }
+                    else if(border_mode == BorderMode::REPLICATE)
+                    {
+                        id.set(0, clamp(static_cast<int>(x_src), 0, width - 1));
+                        id.set(1, clamp(static_cast<int>(y_src), 0, height - 1));
+                        out[element_idx] = in[coord2index(in.shape(), id)];
+                    }
+                }
+                break;
+            }
+            case InterpolationPolicy::BILINEAR:
+            {
+                id.set(0, std::floor(x_src));
+                id.set(1, std::floor(y_src));
+                if(x_src >= -1 || y_src >= -1 || x_src <= width || y_src <= height)
+                {
+                    out[element_idx] = bilinear_policy(in, id, x_src, y_src, border_mode, constant_border_value);
+                }
+                else
+                {
+                    if(border_mode == BorderMode::CONSTANT)
+                    {
+                        out[element_idx] = constant_border_value;
+                    }
+                    else if(border_mode == BorderMode::REPLICATE)
+                    {
+                        id.set(0, clamp(static_cast<int>(x_src), 0, width - 1));
+                        id.set(1, clamp(static_cast<int>(y_src), 0, height - 1));
+                        out[element_idx] = in[coord2index(in.shape(), id)];
+                    }
+                }
+                break;
+            }
+            case InterpolationPolicy::AREA:
+            {
+                int       x_from = std::floor(idx * wr - 0.5f - x_src);
+                int       y_from = std::floor(idy * hr - 0.5f - y_src);
+                int       x_to   = std::ceil((idx + 1) * wr - 0.5f - x_src);
+                int       y_to   = std::ceil((idy + 1) * hr - 0.5f - y_src);
+                const int xi     = std::floor(x_src);
+                const int yi     = std::floor(y_src);
+
+                // Clamp position to borders
+                x_src = std::max(-1.f, std::min(x_src, static_cast<float>(width)));
+                y_src = std::max(-1.f, std::min(y_src, static_cast<float>(height)));
+
+                // Clamp bounding box offsets to borders
+                x_from = ((x_src + x_from) < -1) ? -1 : x_from;
+                y_from = ((y_src + y_from) < -1) ? -1 : y_from;
+                x_to   = ((x_src + x_to) > width) ? (width - x_src) : x_to;
+                y_to   = ((y_src + y_to) > height) ? (height - y_src) : y_to;
+                ARM_COMPUTE_ERROR_ON((x_to - x_from + 1) == 0 || (y_to - y_from + 1) == 0);
+
+                float sum = 0;
+                for(int j = yi + y_from, je = yi + y_to; j <= je; ++j)
+                {
+                    for(int i = xi + x_from, ie = xi + x_to; i <= ie; ++i)
+                    {
+                        id.set(0, static_cast<int>(i));
+                        id.set(1, static_cast<int>(j));
+                        sum += tensor_elem_at(in, id, border_mode, constant_border_value);
+                    }
+                }
+                out[element_idx] = sum / ((x_to - x_from + 1) * (y_to - y_from + 1));
+
+                break;
+            }
+            default:
+                ARM_COMPUTE_ERROR("Unsupported interpolation mode");
+        }
+    }
+
+    return out;
+}
+
+template SimpleTensor<uint8_t> scale(const SimpleTensor<uint8_t> &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, uint8_t constant_border_value);
+template SimpleTensor<int16_t> scale(const SimpleTensor<int16_t> &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, int16_t constant_border_value);
+template SimpleTensor<half> scale(const SimpleTensor<half> &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, half constant_border_value);
+template SimpleTensor<float> scale(const SimpleTensor<float> &src, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, float constant_border_value);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/Scale.h
similarity index 77%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/Scale.h
index 138e056..53183ae 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/Scale.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_SCALE_H__
+#define __ARM_COMPUTE_TEST_SCALE_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> scale(const SimpleTensor<T> &in, float scale_x, float scale_y, InterpolationPolicy policy, BorderMode border_mode, T constant_border_value = 0);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_SCALE_H__ */
diff --git a/tests/validation/CPP/Sobel.cpp b/tests/validation/CPP/Sobel.cpp
new file mode 100644
index 0000000..314fbd4
--- /dev/null
+++ b/tests/validation/CPP/Sobel.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "Sobel.h"
+
+#include "Utils.h"
+#include "tests/validation/Helpers.h"
+
+#include <array>
+#include <map>
+#include <utility>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+namespace
+{
+const std::array<int8_t, 9> sobel_3_x{ { -1, 0, 1, -2, 0, 2, -1, 0, 1 } };
+const std::array<int8_t, 9> sobel_3_y{ { -1, -2, -1, 0, 0, 0, 1, 2, 1 } };
+
+const std::array<int8_t, 25> sobel_5_x{ {
+        -1, -2, 0, 2, 1,
+        -4, -8, 0, 8, 4,
+        -6, -12, 0, 12, 6,
+        -4, -8, 0, 8, 4,
+        -1, -2, 0, 2, 1
+    } };
+
+const std::array<int8_t, 25> sobel_5_y{ {
+        -1, -4, -6, -4, -1,
+        -2, -8, -12, -8, -2,
+        0, 0, 0, 0, 0,
+        2, 8, 12, 8, 2,
+        1, 4, 6, 4, 1
+    } };
+
+const std::array<int8_t, 49> sobel_7_x{ {
+        -1, -4, -5, 0, 5, 4, 1,
+        -6, -24, -30, 0, 30, 24, 6,
+        -15, -60, -75, 0, 75, 60, 15,
+        -20, -80, -100, 0, 100, 80, 20,
+        -15, -60, -75, 0, 75, 60, 15,
+        -6, -24, -30, 0, 30, 24, 6,
+        -1, -4, -5, 0, 5, 4, 1
+    } };
+
+const std::array<int8_t, 49> sobel_7_y{ {
+        -1, -6, -15, -20, -15, -6, -1,
+        -4, -24, -60, -80, -60, -24, -4,
+        -5, -30, -75, -100, -75, -30, -5,
+        0, 0, 0, 0, 0, 0, 0,
+        5, 30, 75, 100, 75, 30, 5,
+        4, 24, 60, 80, 60, 24, 4,
+        1, 6, 15, 20, 15, 6, 1
+    } };
+
+const std::map<int, std::pair<const int8_t *, const int8_t *>> masks
+{
+    { 3, { sobel_3_x.data(), sobel_3_y.data() } },
+    { 5, { sobel_5_x.data(), sobel_5_y.data() } },
+    { 7, { sobel_7_x.data(), sobel_7_y.data() } },
+};
+
+template <typename T>
+struct data_type;
+
+template <>
+struct data_type<int16_t>
+{
+    const static DataType value = DataType::S16;
+};
+
+template <>
+struct data_type<int>
+{
+    const static DataType value = DataType::S32;
+};
+} // namespace
+
+template <typename T, typename U>
+std::pair<SimpleTensor<T>, SimpleTensor<T>> sobel(const SimpleTensor<U> &src, int filter_size, BorderMode border_mode, uint8_t constant_border_value)
+{
+    SimpleTensor<T> dst_x(src.shape(), data_type<T>::value, src.num_channels());
+    SimpleTensor<T> dst_y(src.shape(), data_type<T>::value, src.num_channels());
+
+    ValidRegion valid_region = shape_to_valid_region(src.shape(), border_mode == BorderMode::UNDEFINED, BorderSize(filter_size / 2));
+
+    for(int i = 0; i < src.num_elements(); ++i)
+    {
+        Coordinates coord = index2coord(src.shape(), i);
+
+        if(!is_in_valid_region(valid_region, coord))
+        {
+            continue;
+        }
+
+        apply_2d_spatial_filter(coord, src, dst_x, TensorShape{ static_cast<unsigned int>(filter_size), static_cast<unsigned int>(filter_size) }, masks.at(filter_size).first, 1.f, border_mode,
+                                constant_border_value);
+        apply_2d_spatial_filter(coord, src, dst_y, TensorShape{ static_cast<unsigned int>(filter_size), static_cast<unsigned int>(filter_size) }, masks.at(filter_size).second, 1.f, border_mode,
+                                constant_border_value);
+    }
+
+    return std::make_pair(dst_x, dst_y);
+}
+
+template std::pair<SimpleTensor<int16_t>, SimpleTensor<int16_t>> sobel(const SimpleTensor<uint8_t> &src, int filter_size, BorderMode border_mode, uint8_t constant_border_value);
+template std::pair<SimpleTensor<int>, SimpleTensor<int>> sobel(const SimpleTensor<uint8_t> &src, int filter_size, BorderMode border_mode, uint8_t constant_border_value);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/Sobel.h
similarity index 75%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/Sobel.h
index bf30db9..ab04663 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/Sobel.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_SOBEL_H__
+#define __ARM_COMPUTE_TEST_SOBEL_H__
 
-#include "ProgramOptions.h"
+#include "arm_compute/core/Types.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename U>
+std::pair<SimpleTensor<T>, SimpleTensor<T>> sobel(const SimpleTensor<U> &src, int filter_size, BorderMode border_mode, uint8_t constant_border_value = 0);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_SOBEL_H__ */
diff --git a/tests/validation/CPP/SoftmaxLayer.cpp b/tests/validation/CPP/SoftmaxLayer.cpp
new file mode 100644
index 0000000..eb76550
--- /dev/null
+++ b/tests/validation/CPP/SoftmaxLayer.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "SoftmaxLayer.h"
+
+#include "arm_compute/core/Types.h"
+#include "tests/validation/FixedPoint.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type>
+SimpleTensor<T> softmax_layer(const SimpleTensor<T> &src)
+{
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const int cols       = src.shape()[0];
+    const int upper_dims = src.num_elements() / cols;
+
+    for(int r = 0; r < upper_dims; ++r)
+    {
+        const T *src_row_ptr = src.data() + r * cols;
+        T       *dst_row_ptr = dst.data() + r * cols;
+
+        // Find max
+        const T max = *std::max_element(src_row_ptr, src_row_ptr + cols);
+
+        // Regularize
+        T sum(0.f);
+        std::transform(src_row_ptr, src_row_ptr + cols, dst_row_ptr, [&sum, max](T val)
+        {
+            const T res(std::exp(val - max));
+            sum += res;
+            return res;
+        });
+
+        // Normalize
+        std::transform(dst_row_ptr, dst_row_ptr + cols, dst_row_ptr, [sum](T val)
+        {
+            return val / sum;
+        });
+    }
+
+    return dst;
+}
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type>
+SimpleTensor<T> softmax_layer(const SimpleTensor<T> &src)
+{
+    using namespace fixed_point_arithmetic;
+
+    // Create reference
+    SimpleTensor<T> dst{ src.shape(), src.data_type(), 1, src.fixed_point_position() };
+
+    // Compute reference
+    const int cols       = src.shape()[0];
+    const int upper_dims = src.num_elements() / cols;
+
+    for(int r = 0; r < upper_dims; ++r)
+    {
+        const T *src_row_ptr = src.data() + r * cols;
+        T       *dst_row_ptr = dst.data() + r * cols;
+
+        // Find max
+        const fixed_point<T> max(*std::max_element(src_row_ptr, src_row_ptr + cols), src.fixed_point_position(), true);
+
+        // Regularize
+        using promoted_type = fixed_point_arithmetic::traits::promote_t<T>;
+        fixed_point<promoted_type> sum(0, src.fixed_point_position(), true);
+        std::transform(src_row_ptr, src_row_ptr + cols, dst_row_ptr, [&](T val)
+        {
+            const fixed_point<T> res = exp(fixed_point<T>(val, src.fixed_point_position(), true) - max);
+            sum                      = add(sum, fixed_point<promoted_type>(res.raw(), src.fixed_point_position(), true));
+            return res.raw();
+        });
+
+        // Normalize
+        fixed_point<T> saturated_sum(sum);
+        std::transform(dst_row_ptr, dst_row_ptr + cols, dst_row_ptr, [&](T val)
+        {
+            return div(fixed_point<T>(val, src.fixed_point_position(), true), saturated_sum).raw();
+        });
+    }
+
+    return dst;
+}
+
+template SimpleTensor<float> softmax_layer(const SimpleTensor<float> &src);
+template SimpleTensor<half> softmax_layer(const SimpleTensor<half> &src);
+template SimpleTensor<qint8_t> softmax_layer(const SimpleTensor<qint8_t> &src);
+template SimpleTensor<qint16_t> softmax_layer(const SimpleTensor<qint16_t> &src);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/SoftmaxLayer.h
similarity index 69%
copy from tests/validation/ValidationProgramOptions.h
copy to tests/validation/CPP/SoftmaxLayer.h
index bf30db9..ab79bc4 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/SoftmaxLayer.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_SOFTMAX_LAYER_H__
+#define __ARM_COMPUTE_TEST_SOFTMAX_LAYER_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,15 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T, typename std::enable_if<is_floating_point<T>::value, int>::type = 0>
+SimpleTensor<T> softmax_layer(const SimpleTensor<T> &src);
+
+template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
+SimpleTensor<T> softmax_layer(const SimpleTensor<T> &src);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_SOFTMAX_LAYER_H__ */
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/TableLookup.cpp
similarity index 67%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/TableLookup.cpp
index 138e056..7f105d9 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/TableLookup.cpp
@@ -21,10 +21,9 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#include "TableLookup.h"
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,17 +31,24 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
+template <typename T>
+SimpleTensor<T> table_lookup(const SimpleTensor<T> &src, const std::map<T, T> &rawlut)
 {
-    CLFixture()
+    SimpleTensor<T> result(src.shape(), src.data_type());
+
+    for(int i = 0; i < src.num_elements(); ++i)
     {
-        CLScheduler::get().default_init();
+        result[i] = rawlut.at(src[i]);
     }
-};
-} // namespace cl
+
+    return result;
+}
+
+template SimpleTensor<uint8_t> table_lookup(const SimpleTensor<uint8_t> &src, const std::map<uint8_t, uint8_t> &rawlut);
+template SimpleTensor<int16_t> table_lookup(const SimpleTensor<int16_t> &src, const std::map<int16_t, int16_t> &rawlut);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
diff --git a/tests/validation/ValidationProgramOptions.h b/tests/validation/CPP/TableLookup.h
similarity index 77%
rename from tests/validation/ValidationProgramOptions.h
rename to tests/validation/CPP/TableLookup.h
index bf30db9..3fdecac 100644
--- a/tests/validation/ValidationProgramOptions.h
+++ b/tests/validation/CPP/TableLookup.h
@@ -21,10 +21,11 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_PROGRAM_OPTIONS_H__
+#ifndef __ARM_COMPUTE_TEST_TABLE_LOOKUP_H__
+#define __ARM_COMPUTE_TEST_TABLE_LOOKUP_H__
 
-#include "ProgramOptions.h"
+#include "tests/SimpleTensor.h"
+#include "tests/validation/Helpers.h"
 
 namespace arm_compute
 {
@@ -32,14 +33,12 @@
 {
 namespace validation
 {
-/** Subclass of @ref ProgramOptions that adds validation specific options. */
-class ValidationProgramOptions : public ProgramOptions
+namespace reference
 {
-public:
-    /** Defines additonal options. */
-    ValidationProgramOptions();
-};
+template <typename T>
+SimpleTensor<T> table_lookup(const SimpleTensor<T> &src, const std::map<T, T> &rawlut);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_TABLE_LOOKUP_H__ */
diff --git a/tests/validation/CPP/Threshold.cpp b/tests/validation/CPP/Threshold.cpp
new file mode 100644
index 0000000..d0ef31d
--- /dev/null
+++ b/tests/validation/CPP/Threshold.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017 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 src 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 src 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. src NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER src AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * dst OF OR src CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS src THE
+ * SOFTWARE.
+ */
+#include "Threshold.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace reference
+{
+template <typename T>
+SimpleTensor<T> threshold(const SimpleTensor<T> &src, T threshold, T false_value, T true_value, ThresholdType type, T upper)
+{
+    SimpleTensor<T> dst(src.shape(), src.data_type());
+
+    switch(type)
+    {
+        case ThresholdType::BINARY:
+            for(int i = 0; i < src.num_elements(); ++i)
+            {
+                dst[i] = ((src[i] > threshold) ? true_value : false_value);
+            }
+            break;
+        case ThresholdType::RANGE:
+            for(int i = 0; i < src.num_elements(); ++i)
+            {
+                if(src[i] > upper)
+                {
+                    dst[i] = false_value;
+                }
+                else if(src[i] < threshold)
+                {
+                    dst[i] = false_value;
+                }
+                else
+                {
+                    dst[i] = true_value;
+                }
+            }
+            break;
+        default:
+            ARM_COMPUTE_ERROR("Thresholding type not recognised");
+            break;
+    }
+
+    return dst;
+}
+
+template SimpleTensor<uint8_t> threshold(const SimpleTensor<uint8_t> &src, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper);
+} // namespace reference
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CL/CLFixture.h b/tests/validation/CPP/Threshold.h
similarity index 78%
copy from tests/validation/CL/CLFixture.h
copy to tests/validation/CPP/Threshold.h
index 138e056..fbe2dba 100644
--- a/tests/validation/CL/CLFixture.h
+++ b/tests/validation/CPP/Threshold.h
@@ -21,10 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_CL_CLFIXTURE_H__
+#ifndef __ARM_COMPUTE_TEST_THRESHOLD_H__
+#define __ARM_COMPUTE_TEST_THRESHOLD_H__
 
-#include "arm_compute/runtime/CL/CLScheduler.h"
+#include "tests/SimpleTensor.h"
 
 namespace arm_compute
 {
@@ -32,17 +32,12 @@
 {
 namespace validation
 {
-namespace cl
+namespace reference
 {
-struct CLFixture
-{
-    CLFixture()
-    {
-        CLScheduler::get().default_init();
-    }
-};
-} // namespace cl
+template <typename T>
+SimpleTensor<T> threshold(const SimpleTensor<T> &src, T threshold, T false_value, T true_value, ThresholdType type, T upper);
+} // namespace reference
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_THRESHOLD_H__ */
diff --git a/tests/validation/CPP/Utils.cpp b/tests/validation/CPP/Utils.cpp
new file mode 100644
index 0000000..af3ed90
--- /dev/null
+++ b/tests/validation/CPP/Utils.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "Utils.h"
+
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+// Return the bilinear value at a specified coordinate with different border modes
+template <typename T>
+T bilinear_policy(const SimpleTensor<T> &in, Coordinates id, float xn, float yn, BorderMode border_mode, T constant_border_value)
+{
+    int idx = std::floor(xn);
+    int idy = std::floor(yn);
+
+    const float dx   = xn - idx;
+    const float dy   = yn - idy;
+    const float dx_1 = 1.0f - dx;
+    const float dy_1 = 1.0f - dy;
+
+    const T border_value = constant_border_value;
+
+    id.set(0, idx);
+    id.set(1, idy);
+    const float tl = tensor_elem_at(in, id, border_mode, border_value);
+    id.set(0, idx + 1);
+    id.set(1, idy);
+    const float tr = tensor_elem_at(in, id, border_mode, border_value);
+    id.set(0, idx);
+    id.set(1, idy + 1);
+    const float bl = tensor_elem_at(in, id, border_mode, border_value);
+    id.set(0, idx + 1);
+    id.set(1, idy + 1);
+    const float br = tensor_elem_at(in, id, border_mode, border_value);
+
+    return static_cast<T>(tl * (dx_1 * dy_1) + tr * (dx * dy_1) + bl * (dx_1 * dy) + br * (dx * dy));
+}
+
+template uint8_t bilinear_policy(const SimpleTensor<uint8_t> &in, Coordinates id, float xn, float yn, BorderMode border_mode, uint8_t constant_border_value);
+template int16_t bilinear_policy(const SimpleTensor<int16_t> &in, Coordinates id, float xn, float yn, BorderMode border_mode, int16_t constant_border_value);
+template half bilinear_policy(const SimpleTensor<half> &in, Coordinates id, float xn, float yn, BorderMode border_mode, half constant_border_value);
+template float bilinear_policy(const SimpleTensor<float> &in, Coordinates id, float xn, float yn, BorderMode border_mode, float constant_border_value);
+
+RawTensor transpose(const RawTensor &src, int chunk_width)
+{
+    // Create reference
+    TensorShape dst_shape(src.shape());
+    dst_shape.set(0, src.shape().y() * chunk_width);
+    dst_shape.set(1, std::ceil(src.shape().x() / static_cast<float>(chunk_width)));
+
+    RawTensor dst{ dst_shape, src.data_type() };
+
+    // Compute reference
+    uint8_t *out_ptr = dst.data();
+
+    for(int i = 0; i < dst.num_elements(); i += chunk_width)
+    {
+        Coordinates coord   = index2coord(dst.shape(), i);
+        size_t      coord_x = coord.x();
+        coord.set(0, coord.y() * chunk_width);
+        coord.set(1, coord_x / chunk_width);
+
+        const int num_elements = std::min<int>(chunk_width, src.shape().x() - coord.x());
+
+        std::copy_n(static_cast<const uint8_t *>(src(coord)), num_elements * src.element_size(), out_ptr);
+
+        out_ptr += chunk_width * dst.element_size();
+    }
+
+    return dst;
+}
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/CPP/Utils.h b/tests/validation/CPP/Utils.h
new file mode 100644
index 0000000..91d1afe
--- /dev/null
+++ b/tests/validation/CPP/Utils.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 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_TEST_VALIDATION_UTILS_H__
+#define __ARM_COMPUTE_TEST_VALIDATION_UTILS_H__
+
+#include "arm_compute/core/Types.h"
+#include "tests/Globals.h"
+#include "tests/ILutAccessor.h"
+#include "tests/Types.h"
+
+#include <array>
+#include <random>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+// Return a tensor element at a specified coordinate with different border modes
+template <typename T>
+T tensor_elem_at(const SimpleTensor<T> &src, Coordinates coord, BorderMode border_mode, T constant_border_value)
+{
+    const int x      = coord.x();
+    const int y      = coord.y();
+    const int width  = src.shape().x();
+    const int height = src.shape().y();
+
+    // If coordinates beyond range of tensor's width or height
+    if(x < 0 || y < 0 || x >= width || y >= height)
+    {
+        if(border_mode == BorderMode::REPLICATE)
+        {
+            coord.set(0, std::max(0, std::min(x, width - 1)));
+            coord.set(1, std::max(0, std::min(y, height - 1)));
+        }
+        else
+        {
+            return constant_border_value;
+        }
+    }
+
+    return src[coord2index(src.shape(), coord)];
+}
+
+template <typename T>
+T bilinear_policy(const SimpleTensor<T> &in, Coordinates id, float xn, float yn, BorderMode border_mode, T constant_border_value);
+
+/* Apply 2D spatial filter on a single element of @p in at coordinates @p coord
+ *
+ * - filter sizes have to be odd number
+ * - Row major order of filter assumed
+ * - TO_ZERO rounding policy assumed
+ * - SATURATE convert policy assumed
+ */
+template <typename T, typename U, typename V>
+void apply_2d_spatial_filter(Coordinates coord, const SimpleTensor<T> &src, SimpleTensor<U> &dst, const TensorShape &filter_shape, const V *filter_itr, double scale, BorderMode border_mode,
+                             T constant_border_value = T(0))
+{
+    double    val = 0.;
+    const int x   = coord.x();
+    const int y   = coord.y();
+    for(int j = y - static_cast<int>(filter_shape[1] / 2); j <= y + static_cast<int>(filter_shape[1] / 2); ++j)
+    {
+        for(int i = x - static_cast<int>(filter_shape[0] / 2); i <= x + static_cast<int>(filter_shape[0] / 2); ++i)
+        {
+            coord.set(0, i);
+            coord.set(1, j);
+            val += static_cast<double>(*filter_itr) * tensor_elem_at(src, coord, border_mode, constant_border_value);
+            ++filter_itr;
+        }
+    }
+    coord.set(0, x);
+    coord.set(1, y);
+    dst[coord2index(src.shape(), coord)] = saturate_cast<U>(support::cpp11::trunc(val * scale));
+}
+
+RawTensor transpose(const RawTensor &src, int chunk_width = 1);
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* __ARM_COMPUTE_TEST_VALIDATION_UTILS_H__ */
diff --git a/tests/validation/Datasets.h b/tests/validation/Datasets.h
deleted file mode 100644
index ae76fb6..0000000
--- a/tests/validation/Datasets.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_VALIDATION_DATASETS_H__
-#define __ARM_COMPUTE_TEST_VALIDATION_DATASETS_H__
-
-#include "dataset/ActivationFunctionDataset.h"
-#include "dataset/BatchNormalizationLayerDataset.h"
-#include "dataset/BorderModeDataset.h"
-#include "dataset/ConvertPolicyDataset.h"
-#include "dataset/ConvolutionLayerDataset.h"
-#include "dataset/DataTypeDatasets.h"
-#include "dataset/FullyConnectedLayerDataset.h"
-#include "dataset/GEMMDataset.h"
-#include "dataset/ImageDatasets.h"
-#include "dataset/InterpolationPolicyDataset.h"
-#include "dataset/NormalizationTypeDataset.h"
-#include "dataset/PoolingLayerDataset.h"
-#include "dataset/RoundingPolicyDataset.h"
-#include "dataset/ShapeDatasets.h"
-#include "dataset/ThresholdDataset.h"
-
-#include "boost_wrapper.h"
-
-using namespace boost::unit_test::data::monomorphic;
-
-namespace boost
-{
-namespace unit_test
-{
-namespace data
-{
-namespace monomorphic
-{
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::SmallImages> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::LargeImages> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::SmallShapes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::Small1DShape> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::LargeShapes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::AllDataTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::UnsignedDataTypes> : boost::mpl::true_
-{
-};
-
-// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::SignedDataTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::FloatDataTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::FixedPointDataTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::CNNFloatDataTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::CNNFixedPointDataTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::CNNDataTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::ActivationFunctions> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::BorderModes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::ConvertPolicies> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::InterpolationPolicies> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::NormalizationTypes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::RandomPoolingLayerDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::RoundingPolicies> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::AlexNetConvolutionLayerDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::AlexNetFullyConnectedLayerDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::DirectConvolutionShapes> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::SmallFullyConnectedLayerDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::LargeFullyConnectedLayerDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::SmallConvolutionLayerDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::SmallGEMMDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::LargeGEMMDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::RandomBatchNormalizationLayerDataset> : boost::mpl::true_
-{
-};
-
-/// Register the data set with Boost
-template <>
-struct is_dataset<arm_compute::test::ThresholdDataset> : boost::mpl::true_
-{
-};
-}
-}
-}
-}
-#endif
diff --git a/tests/validation/FixedPoint.h b/tests/validation/FixedPoint.h
index d1c0503..6699aee 100644
--- a/tests/validation/FixedPoint.h
+++ b/tests/validation/FixedPoint.h
@@ -24,7 +24,8 @@
 #ifndef __ARM_COMPUTE_TEST_VALIDATION_FIXEDPOINT_H__
 #define __ARM_COMPUTE_TEST_VALIDATION_FIXEDPOINT_H__
 
-#include "Utils.h"
+#include "support/ToolchainSupport.h"
+#include "tests/Utils.h"
 
 #include <cassert>
 #include <cstdint>
@@ -62,6 +63,8 @@
 template <> struct promote<int32_t> { using type = int64_t; };
 template <> struct promote<uint64_t> { using type = uint64_t; };
 template <> struct promote<int64_t> { using type = int64_t; };
+template <typename T>
+using promote_t = typename promote<T>::type;
 // clang-format on
 // *INDENT-ON*
 }
@@ -87,10 +90,6 @@
     // Static Checks
     static_assert(std::is_integral<T>::value, "Type is not an integer");
 
-    // Friends
-    friend struct detail::functions;
-    friend struct detail::constant_expr<T>;
-
     /** Constructor (from different fixed point type)
      *
      * @param[in] val Fixed point
@@ -147,7 +146,7 @@
      * @param[in] p   Fixed point precision
      */
     fixed_point(std::string str, uint8_t p)
-        : _value(detail::constant_expr<T>::to_fixed(arm_compute::test::cpp11::stof(str), p)), _fixed_point_position(p)
+        : _value(detail::constant_expr<T>::to_fixed(support::cpp11::stof(str), p)), _fixed_point_position(p)
     {
         assert(p > 0 && p < std::numeric_limits<T>::digits);
     }
@@ -243,15 +242,20 @@
     {
         assert(p > 0 && p < std::numeric_limits<T>::digits);
 
+        using promoted_T = typename traits::promote<T>::type;
+        promoted_T val   = _value;
         if(p > _fixed_point_position)
         {
-            _value <<= (p - _fixed_point_position);
+            val <<= (p - _fixed_point_position);
         }
         else if(p < _fixed_point_position)
         {
-            _value >>= (_fixed_point_position - p);
+            uint8_t pbar = _fixed_point_position - p;
+            val += (pbar != 0) ? (1 << (pbar - 1)) : 0;
+            val >>= pbar;
         }
 
+        _value                = detail::constant_expr<T>::saturate_cast(val);
         _fixed_point_position = p;
     }
 
@@ -332,7 +336,7 @@
      */
     static constexpr T to_fixed(float val, uint8_t p)
     {
-        return static_cast<T>(val * fixed_one(p) + ((val >= 0) ? 0.5 : -0.5));
+        return static_cast<T>(saturate_cast<float>(val * fixed_one(p) + ((val >= 0) ? 0.5 : -0.5)));
     }
     /** Clamp value between two ranges
      *
@@ -381,7 +385,7 @@
     template <typename T>
     static bool signbit(fixed_point<T> x)
     {
-        return ((x._value >> std::numeric_limits<T>::digits) != 0);
+        return ((x.raw() >> std::numeric_limits<T>::digits) != 0);
     }
     /** Checks if two fixed point numbers are equal
      *
@@ -393,10 +397,10 @@
     template <typename T>
     static bool isequal(fixed_point<T> x, fixed_point<T> y)
     {
-        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
+        uint8_t p = std::min(x.precision(), y.precision());
         x.rescale(p);
         y.rescale(p);
-        return (x._value == y._value);
+        return (x.raw() == y.raw());
     }
     /** Checks if two fixed point number are not equal
      *
@@ -420,10 +424,10 @@
     template <typename T>
     static bool isgreater(fixed_point<T> x, fixed_point<T> y)
     {
-        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
+        uint8_t p = std::min(x.precision(), y.precision());
         x.rescale(p);
         y.rescale(p);
-        return (x._value > y._value);
+        return (x.raw() > y.raw());
     }
     /** Checks if one fixed point is greater or equal than the other
      *
@@ -435,10 +439,10 @@
     template <typename T>
     static bool isgreaterequal(fixed_point<T> x, fixed_point<T> y)
     {
-        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
+        uint8_t p = std::min(x.precision(), y.precision());
         x.rescale(p);
         y.rescale(p);
-        return (x._value >= y._value);
+        return (x.raw() >= y.raw());
     }
     /** Checks if one fixed point is less than the other
      *
@@ -450,10 +454,10 @@
     template <typename T>
     static bool isless(fixed_point<T> x, fixed_point<T> y)
     {
-        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
+        uint8_t p = std::min(x.precision(), y.precision());
         x.rescale(p);
         y.rescale(p);
-        return (x._value < y._value);
+        return (x.raw() < y.raw());
     }
     /** Checks if one fixed point is less or equal than the other
      *
@@ -465,10 +469,10 @@
     template <typename T>
     static bool islessequal(fixed_point<T> x, fixed_point<T> y)
     {
-        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
+        uint8_t p = std::min(x.precision(), y.precision());
         x.rescale(p);
         y.rescale(p);
-        return (x._value <= y._value);
+        return (x.raw() <= y.raw());
     }
     /** Checks if one fixed point is less or greater than the other
      *
@@ -493,7 +497,7 @@
     template <typename T>
     static fixed_point<T> clamp(fixed_point<T> x, T min, T max)
     {
-        return fixed_point<T>(constant_expr<T>::clamp(x._value, min, max), x._fixed_point_position, true);
+        return fixed_point<T>(constant_expr<T>::clamp(x.raw(), min, max), x.precision(), true);
     }
     /** Negate number
      *
@@ -505,12 +509,12 @@
     static fixed_point<T> negate(fixed_point<T> x)
     {
         using promoted_T = typename traits::promote<T>::type;
-        promoted_T val   = -x._value;
+        promoted_T val   = -x.raw();
         if(OP == OverflowPolicy::SATURATE)
         {
             val = constant_expr<T>::saturate_cast(val);
         }
-        return fixed_point<T>(static_cast<T>(val), x._fixed_point_position, true);
+        return fixed_point<T>(static_cast<T>(val), x.precision(), true);
     }
     /** Perform addition among two fixed point numbers
      *
@@ -522,19 +526,19 @@
     template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
     static fixed_point<T> add(fixed_point<T> x, fixed_point<T> y)
     {
-        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
+        uint8_t p = std::min(x.precision(), y.precision());
         x.rescale(p);
         y.rescale(p);
         if(OP == OverflowPolicy::SATURATE)
         {
             using type = typename traits::promote<T>::type;
-            type val   = static_cast<type>(x._value) + static_cast<type>(y._value);
+            type val   = static_cast<type>(x.raw()) + static_cast<type>(y.raw());
             val        = constant_expr<T>::saturate_cast(val);
             return fixed_point<T>(static_cast<T>(val), p, true);
         }
         else
         {
-            return fixed_point<T>(x._value + y._value, p, true);
+            return fixed_point<T>(x.raw() + y.raw(), p, true);
         }
     }
     /** Perform subtraction among two fixed point numbers
@@ -547,19 +551,19 @@
     template <OverflowPolicy OP = OverflowPolicy::SATURATE, typename T>
     static fixed_point<T> sub(fixed_point<T> x, fixed_point<T> y)
     {
-        uint8_t p = std::min(x._fixed_point_position, y._fixed_point_position);
+        uint8_t p = std::min(x.precision(), y.precision());
         x.rescale(p);
         y.rescale(p);
         if(OP == OverflowPolicy::SATURATE)
         {
             using type = typename traits::promote<T>::type;
-            type val   = static_cast<type>(x._value) - static_cast<type>(y._value);
+            type val   = static_cast<type>(x.raw()) - static_cast<type>(y.raw());
             val        = constant_expr<T>::saturate_cast(val);
             return fixed_point<T>(static_cast<T>(val), p, true);
         }
         else
         {
-            return fixed_point<T>(x._value - y._value, p, true);
+            return fixed_point<T>(x.raw() - y.raw(), p, true);
         }
     }
     /** Perform multiplication among two fixed point numbers
@@ -573,10 +577,10 @@
     static fixed_point<T> mul(fixed_point<T> x, fixed_point<T> y)
     {
         using promoted_T        = typename traits::promote<T>::type;
-        uint8_t    p_min        = std::min(x._fixed_point_position, y._fixed_point_position);
-        uint8_t    p_max        = std::max(x._fixed_point_position, y._fixed_point_position);
+        uint8_t    p_min        = std::min(x.precision(), y.precision());
+        uint8_t    p_max        = std::max(x.precision(), y.precision());
         promoted_T round_factor = (1 << (p_max - 1));
-        promoted_T val          = ((static_cast<promoted_T>(x._value) * static_cast<promoted_T>(y._value)) + round_factor) >> p_max;
+        promoted_T val          = ((static_cast<promoted_T>(x.raw()) * static_cast<promoted_T>(y.raw())) + round_factor) >> p_max;
         if(OP == OverflowPolicy::SATURATE)
         {
             val = constant_expr<T>::saturate_cast(val);
@@ -594,11 +598,11 @@
     static fixed_point<T> div(fixed_point<T> x, fixed_point<T> y)
     {
         using promoted_T = typename traits::promote<T>::type;
-        uint8_t    p     = std::min(x._fixed_point_position, y._fixed_point_position);
-        promoted_T denom = static_cast<promoted_T>(y._value);
+        uint8_t    p     = std::min(x.precision(), y.precision());
+        promoted_T denom = static_cast<promoted_T>(y.raw());
         if(denom != 0)
         {
-            promoted_T val = (static_cast<promoted_T>(x._value) << std::max(x._fixed_point_position, y._fixed_point_position)) / denom;
+            promoted_T val = (static_cast<promoted_T>(x.raw()) << std::max(x.precision(), y.precision())) / denom;
             if(OP == OverflowPolicy::SATURATE)
             {
                 val = constant_expr<T>::saturate_cast(val);
@@ -607,7 +611,7 @@
         }
         else
         {
-            T val = (x._value < 0) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
+            T val = (x.raw() < 0) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
             return fixed_point<T>(val, p, true);
         }
     }
@@ -622,12 +626,12 @@
     static fixed_point<T> shift_left(fixed_point<T> x, size_t shift)
     {
         using promoted_T = typename traits::promote<T>::type;
-        promoted_T val   = static_cast<promoted_T>(x._value) << shift;
+        promoted_T val   = static_cast<promoted_T>(x.raw()) << shift;
         if(OP == OverflowPolicy::SATURATE)
         {
             val = constant_expr<T>::saturate_cast(val);
         }
-        return fixed_point<T>(static_cast<T>(val), x._fixed_point_position, true);
+        return fixed_point<T>(static_cast<T>(val), x.precision(), true);
     }
     /** Shift right
      *
@@ -639,7 +643,7 @@
     template <typename T>
     static fixed_point<T> shift_right(fixed_point<T> x, size_t shift)
     {
-        return fixed_point<T>(x._value >> shift, x._fixed_point_position, true);
+        return fixed_point<T>(x.raw() >> shift, x.precision(), true);
     }
     /** Calculate absolute value
      *
@@ -651,8 +655,8 @@
     static fixed_point<T> abs(fixed_point<T> x)
     {
         using promoted_T = typename traits::promote<T>::type;
-        T val            = (x._value < 0) ? constant_expr<T>::saturate_cast(-static_cast<promoted_T>(x._value)) : x._value;
-        return fixed_point<T>(val, x._fixed_point_position, true);
+        T val            = (x.raw() < 0) ? constant_expr<T>::saturate_cast(-static_cast<promoted_T>(x.raw())) : x.raw();
+        return fixed_point<T>(val, x.precision(), true);
     }
     /** Calculate the logarithm of a fixed point number
      *
@@ -663,7 +667,7 @@
     template <typename T>
     static fixed_point<T> log(fixed_point<T> x)
     {
-        uint8_t p         = x._fixed_point_position;
+        uint8_t p         = x.precision();
         auto    const_one = fixed_point<T>(static_cast<T>(1), p);
 
         // Logarithm of 1 is zero and logarithm of negative values is not defined in R, so return 0.
@@ -678,7 +682,7 @@
         }
 
         // Remove even powers of 2
-        T shift_val = 31 - __builtin_clz(x._value >> p);
+        T shift_val = 31 - __builtin_clz(x.raw() >> p);
         x           = shift_right(x, shift_val);
         x           = sub(x, const_one);
 
@@ -710,7 +714,7 @@
     template <typename T>
     static fixed_point<T> exp(fixed_point<T> x)
     {
-        uint8_t p = x._fixed_point_position;
+        uint8_t p = x.precision();
         // Constants
         auto const_one = fixed_point<T>(1, p);
         auto ln2       = fixed_point<T>(0.6931471, p);
@@ -720,7 +724,7 @@
         auto C         = fixed_point<T>(0.1763723, p);
         auto D         = fixed_point<T>(0.0435108, p);
 
-        T scaled_int_part = detail::constant_expr<T>::to_int(mul(x, inv_ln2)._value, p);
+        T scaled_int_part = detail::constant_expr<T>::to_int(mul(x, inv_ln2).raw(), p);
 
         // Polynomial expansion
         auto frac_part = sub(x, mul(ln2, fixed_point<T>(scaled_int_part, p)));
@@ -747,22 +751,27 @@
     template <typename T>
     static fixed_point<T> inv_sqrt(fixed_point<T> x)
     {
-        const uint8_t p     = x._fixed_point_position;
-        int8_t        shift = std::numeric_limits<T>::digits - (p + detail::clz(x._value));
+        const uint8_t p     = x.precision();
+        int8_t        shift = std::numeric_limits<T>::digits - (p + detail::clz(x.raw()));
 
         shift += std::numeric_limits<T>::is_signed ? 1 : 0;
 
-        const auto           three_half = fixed_point<T>(1.5f, p);
-        fixed_point<T>       a          = shift < 0 ? shift_left(x, -shift) : shift_right(x, shift);
-        const fixed_point<T> x_half     = shift_right(a, 1);
+        // Use volatile to restrict compiler optimizations on shift as compiler reports maybe-uninitialized error on Android
+        volatile int8_t *shift_ptr = &shift;
 
-        // We need three iterations to find the result
-        for(int i = 0; i < 3; ++i)
+        auto           const_three = fixed_point<T>(3, p);
+        auto           a           = (*shift_ptr < 0) ? shift_left(x, -(shift)) : shift_right(x, shift);
+        fixed_point<T> x2          = a;
+
+        // We need three iterations to find the result for QS8 and five for QS16
+        constexpr int num_iterations = std::is_same<T, int8_t>::value ? 3 : 5;
+        for(int i = 0; i < num_iterations; ++i)
         {
-            a = mul(a, sub(three_half, mul(x_half, mul(a, a))));
+            fixed_point<T> three_minus_dx = sub(const_three, mul(a, mul(x2, x2)));
+            x2                            = shift_right(mul(x2, three_minus_dx), 1);
         }
 
-        return (shift < 0) ? shift_left(a, -shift >> 1) : shift_right(a, shift >> 1);
+        return (shift < 0) ? shift_left(x2, (-shift) >> 1) : shift_right(x2, shift >> 1);
     }
     /** Calculate the hyperbolic tangent of a fixed point number
      *
@@ -773,7 +782,7 @@
     template <typename T>
     static fixed_point<T> tanh(fixed_point<T> x)
     {
-        uint8_t p = x._fixed_point_position;
+        uint8_t p = x.precision();
         // Constants
         auto const_one = fixed_point<T>(1, p);
         auto const_two = fixed_point<T>(2, p);
diff --git a/tests/validation/Helpers.cpp b/tests/validation/Helpers.cpp
new file mode 100644
index 0000000..23ad62a
--- /dev/null
+++ b/tests/validation/Helpers.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+void fill_mask_from_pattern(uint8_t *mask, int cols, int rows, MatrixPattern pattern)
+{
+    unsigned int                v = 0;
+    std::mt19937                gen(library->seed());
+    std::bernoulli_distribution dist(0.5);
+
+    for(int r = 0; r < rows; ++r)
+    {
+        for(int c = 0; c < cols; ++c, ++v)
+        {
+            uint8_t val = 0;
+
+            switch(pattern)
+            {
+                case MatrixPattern::BOX:
+                    val = 255;
+                    break;
+                case MatrixPattern::CROSS:
+                    val = ((r == (rows / 2)) || (c == (cols / 2))) ? 255 : 0;
+                    break;
+                case MatrixPattern::DISK:
+                    val = (((r - rows / 2.0f + 0.5f) * (r - rows / 2.0f + 0.5f)) / ((rows / 2.0f) * (rows / 2.0f)) + ((c - cols / 2.0f + 0.5f) * (c - cols / 2.0f + 0.5f)) / ((cols / 2.0f) *
+                            (cols / 2.0f))) <= 1.0f ? 255 : 0;
+                    break;
+                case MatrixPattern::OTHER:
+                    val = (dist(gen) ? 0 : 255);
+                    break;
+                default:
+                    return;
+            }
+
+            mask[v] = val;
+        }
+    }
+
+    if(pattern == MatrixPattern::OTHER)
+    {
+        std::uniform_int_distribution<uint8_t> distribution_u8(0, ((cols * rows) - 1));
+        mask[distribution_u8(gen)] = 255;
+    }
+}
+
+TensorShape calculate_depth_concatenate_shape(const std::vector<TensorShape> &input_shapes)
+{
+    ARM_COMPUTE_ERROR_ON(input_shapes.empty());
+
+    TensorShape out_shape = input_shapes[0];
+
+    size_t max_x = 0;
+    size_t max_y = 0;
+    size_t depth = 0;
+
+    for(const auto &shape : input_shapes)
+    {
+        max_x = std::max(shape.x(), max_x);
+        max_y = std::max(shape.y(), max_y);
+        depth += shape.z();
+    }
+
+    out_shape.set(0, max_x);
+    out_shape.set(1, max_y);
+    out_shape.set(2, depth);
+
+    return out_shape;
+}
+
+HarrisCornersParameters harris_corners_parameters()
+{
+    HarrisCornersParameters params;
+
+    std::mt19937                           gen(library->seed());
+    std::uniform_real_distribution<float>  threshold_dist(0.f, 0.01f);
+    std::uniform_real_distribution<float>  sensitivity(0.04f, 0.15f);
+    std::uniform_real_distribution<float>  euclidean_distance(0.f, 30.f);
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+
+    params.threshold             = threshold_dist(gen);
+    params.sensitivity           = sensitivity(gen);
+    params.min_dist              = euclidean_distance(gen);
+    params.constant_border_value = int_dist(gen);
+
+    return params;
+}
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/Helpers.h b/tests/validation/Helpers.h
index cbaea4b..eecf976 100644
--- a/tests/validation/Helpers.h
+++ b/tests/validation/Helpers.h
@@ -24,8 +24,13 @@
 #ifndef __ARM_COMPUTE_TEST_VALIDATION_HELPERS_H__
 #define __ARM_COMPUTE_TEST_VALIDATION_HELPERS_H__
 
-#include "Types.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/core/Utils.h"
+#include "support/Half.h"
+#include "tests/Globals.h"
+#include "tests/SimpleTensor.h"
 
+#include <random>
 #include <type_traits>
 #include <utility>
 
@@ -35,64 +40,143 @@
 {
 namespace validation
 {
+template <typename T>
+struct is_floating_point : public std::is_floating_point<T>
+{
+};
+
+template <>
+struct is_floating_point<half> : public std::true_type
+{
+};
+
 /** Helper function to get the testing range for each activation layer.
  *
  * @param[in] activation           Activation function to test.
- * @param[in] fixed_point_position (Optional) Number of bits for the fractional part. Defaults to 1.
+ * @param[in] data_type            Data type.
+ * @param[in] fixed_point_position Number of bits for the fractional part. Defaults to 1.
  *
  * @return A pair containing the lower upper testing bounds for a given function.
  */
 template <typename T>
-std::pair<T, T> get_activation_layer_test_bounds(ActivationLayerInfo::ActivationFunction activation, int fixed_point_position = 1)
+std::pair<T, T> get_activation_layer_test_bounds(ActivationLayerInfo::ActivationFunction activation, DataType data_type, int fixed_point_position = 0)
 {
-    bool is_float = std::is_floating_point<T>::value;
     std::pair<T, T> bounds;
 
-    // Set initial values
-    if(is_float)
+    switch(data_type)
     {
-        bounds = std::make_pair(-255.f, 255.f);
-    }
-    else
-    {
-        bounds = std::make_pair(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
-    }
+        case DataType::F16:
+        {
+            using namespace half_float::literal;
 
-    // Reduce testing ranges
-    switch(activation)
-    {
-        case ActivationLayerInfo::ActivationFunction::LOGISTIC:
-        case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
-            // Reduce range as exponent overflows
-            if(is_float)
+            switch(activation)
             {
-                bounds.first  = -40.f;
-                bounds.second = 40.f;
-            }
-            else
-            {
-                bounds.first  = -(1 << (fixed_point_position));
-                bounds.second = 1 << (fixed_point_position);
+                case ActivationLayerInfo::ActivationFunction::SQUARE:
+                case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+                case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+                    // Reduce range as exponent overflows
+                    bounds = std::make_pair(-10._h, 10._h);
+                    break;
+                case ActivationLayerInfo::ActivationFunction::SQRT:
+                    // Reduce range as sqrt should take a non-negative number
+                    bounds = std::make_pair(0._h, 255._h);
+                    break;
+                default:
+                    bounds = std::make_pair(-255._h, 255._h);
+                    break;
             }
             break;
-        case ActivationLayerInfo::ActivationFunction::TANH:
-            // Reduce range as exponent overflows
-            if(!is_float)
+        }
+        case DataType::F32:
+            switch(activation)
             {
-                bounds.first  = -(1 << (fixed_point_position));
-                bounds.second = 1 << (fixed_point_position);
+                case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+                case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+                    // Reduce range as exponent overflows
+                    bounds = std::make_pair(-40.f, 40.f);
+                    break;
+                case ActivationLayerInfo::ActivationFunction::SQRT:
+                    // Reduce range as sqrt should take a non-negative number
+                    bounds = std::make_pair(0.f, 255.f);
+                    break;
+                default:
+                    bounds = std::make_pair(-255.f, 255.f);
+                    break;
             }
             break;
-        case ActivationLayerInfo::ActivationFunction::SQRT:
-            // Reduce range as sqrt should take a non-negative number
-            bounds.first = (is_float) ? 0 : 1 << (fixed_point_position);
+        case DataType::QS8:
+        case DataType::QS16:
+            switch(activation)
+            {
+                case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+                case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+                case ActivationLayerInfo::ActivationFunction::TANH:
+                    // Reduce range as exponent overflows
+                    bounds = std::make_pair(-(1 << fixed_point_position), 1 << fixed_point_position);
+                    break;
+                case ActivationLayerInfo::ActivationFunction::SQRT:
+                    // Reduce range as sqrt should take a non-negative number
+                    // Can't be zero either as inv_sqrt is used in NEON.
+                    bounds = std::make_pair(1, std::numeric_limits<T>::max());
+                    break;
+                default:
+                    bounds = std::make_pair(std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
+                    break;
+            }
             break;
         default:
-            break;
+            ARM_COMPUTE_ERROR("Unsupported data type");
     }
+
     return bounds;
 }
 
+/** Fill mask with the corresponding given pattern.
+ *
+ * @param[in,out] mask    Mask to be filled according to pattern
+ * @param[in]     cols    Columns (width) of mask
+ * @param[in]     rows    Rows (height) of mask
+ * @param[in]     pattern Pattern to fill the mask according to
+ */
+void fill_mask_from_pattern(uint8_t *mask, int cols, int rows, MatrixPattern pattern);
+
+/** Calculate output tensor shape give a vector of input tensor to concatenate
+ *
+ * @param[in] input_shapes Shapes of the tensors to concatenate across depth.
+ *
+ * @return The shape of output concatenated tensor.
+ */
+TensorShape calculate_depth_concatenate_shape(const std::vector<TensorShape> &input_shapes);
+
+/** Parameters of Harris Corners algorithm. */
+struct HarrisCornersParameters
+{
+    float   threshold{ 0.f };
+    float   sensitivity{ 0.f };
+    float   min_dist{ 0.f };
+    uint8_t constant_border_value{ 0 };
+};
+
+/** Generate parameters for Harris Corners algorithm. */
+HarrisCornersParameters harris_corners_parameters();
+
+/** Helper function to fill the Lut random by a ILutAccessor.
+ *
+ * @param[in,out] table Accessor at the Lut.
+ *
+ */
+template <typename T>
+void fill_lookuptable(T &&table)
+{
+    std::mt19937                                          generator(library->seed());
+    std::uniform_int_distribution<typename T::value_type> distribution(std::numeric_limits<typename T::value_type>::min(), std::numeric_limits<typename T::value_type>::max());
+
+    for(int i = std::numeric_limits<typename T::value_type>::min(); i <= std::numeric_limits<typename T::value_type>::max(); i++)
+    {
+        table[i] = distribution(generator);
+    }
+}
+
 /** Helper function to get the testing range for batch normalization layer.
  *
  * @param[in] fixed_point_position (Optional) Number of bits for the fractional part. Defaults to 1.
@@ -120,4 +204,4 @@
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif //__ARM_COMPUTE_TEST_VALIDATION_HELPERS_H__
+#endif /* __ARM_COMPUTE_TEST_VALIDATION_HELPERS_H__ */
diff --git a/tests/validation/NEON/AbsoluteDifference.cpp b/tests/validation/NEON/AbsoluteDifference.cpp
deleted file mode 100644
index b7f45d2..0000000
--- a/tests/validation/NEON/AbsoluteDifference.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/functions/NEAbsoluteDifference.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-/** Compute Neon absolute difference function.
- *
- * @param[in] shape  Shape of the input and output tensors.
- * @param[in] dt_in0 Data type of first input tensor.
- * @param[in] dt_in1 Data type of second input tensor.
- * @param[in] dt_out Data type of the output tensor.
- *
- * @return Computed output tensor.
- */
-Tensor compute_absolute_difference(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, dt_in0);
-    Tensor src2 = create_tensor(shape, dt_in1);
-    Tensor dst  = create_tensor(shape, dt_out);
-
-    // Create and configure function
-    NEAbsoluteDifference abs_d;
-    abs_d.configure(&src1, &src2, &dst);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-    library->fill_tensor_uniform(NEAccessor(src2), 1);
-
-    // Compute function
-    abs_d.run();
-
-    return dst;
-}
-
-void validate_configuration(const Tensor &src1, const Tensor &src2, Tensor &dst, TensorShape shape)
-{
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEAbsoluteDifference abs_d;
-    abs_d.configure(&src1, &src2, &dst);
-
-    // Validate valid region
-    const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src1.info()->valid_region(), valid_region);
-    validate(src2.info()->valid_region(), valid_region);
-    validate(dst.info()->valid_region(), valid_region);
-
-    // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src1.info()->padding(), padding);
-    validate(src2.info()->padding(), padding);
-    validate(dst.info()->padding(), padding);
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(AbsoluteDifference)
-
-BOOST_AUTO_TEST_SUITE(U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()),
-                     shape)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    validate_configuration(src1, src2, dst, shape);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(),
-                     shape)
-{
-    // Compute function
-    Tensor dst = compute_absolute_difference(shape, DataType::U8, DataType::U8, DataType::U8);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_absolute_difference(shape, DataType::U8, DataType::U8, DataType::U8);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(),
-                     shape)
-{
-    // Compute function
-    Tensor dst = compute_absolute_difference(shape, DataType::U8, DataType::U8, DataType::U8);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_absolute_difference(shape, DataType::U8, DataType::U8, DataType::U8);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(S16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ DataType::U8, DataType::S16 }),
-                     shape, dt)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, dt);
-    Tensor src2 = create_tensor(shape, DataType::S16);
-    Tensor dst  = create_tensor(shape, DataType::S16);
-
-    validate_configuration(src1, src2, dst, shape);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }),
-                     shape, dt)
-{
-    // Compute function
-    Tensor dst = compute_absolute_difference(shape, dt, DataType::S16, DataType::S16);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_absolute_difference(shape, dt, DataType::S16, DataType::S16);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }),
-                     shape, dt)
-{
-    // Compute function
-    Tensor dst = compute_absolute_difference(shape, dt, DataType::S16, DataType::S16);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_absolute_difference(shape, dt, DataType::S16, DataType::S16);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/Accumulate.cpp b/tests/validation/NEON/Accumulate.cpp
deleted file mode 100644
index e3ea37c..0000000
--- a/tests/validation/NEON/Accumulate.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/functions/NEAccumulate.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-/** Compute Neon accumulate function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_accumulate(const TensorShape &shape)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::S16);
-
-    // Create and configure function
-    NEAccumulate acc;
-    acc.configure(&src, &dst);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src), 0);
-    library->fill_tensor_uniform(NEAccessor(dst), 1);
-
-    // Compute function
-    acc.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(Accumulate)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()),
-                     shape)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::S16);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEAccumulate acc;
-    acc.configure(&src, &dst);
-
-    // Validate valid region
-    const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src.info()->valid_region(), valid_region);
-    validate(dst.info()->valid_region(), valid_region);
-
-    // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src.info()->padding(), padding);
-    validate(dst.info()->padding(), padding);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(),
-                     shape)
-{
-    // Compute function
-    Tensor dst = compute_accumulate(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_accumulate(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(),
-                     shape)
-{
-    // Compute function
-    Tensor dst = compute_accumulate(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_accumulate(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/AccumulateSquared.cpp b/tests/validation/NEON/AccumulateSquared.cpp
deleted file mode 100644
index 10263a0..0000000
--- a/tests/validation/NEON/AccumulateSquared.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/functions/NEAccumulate.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-/** Compute Neon accumulate squared function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_accumulate_squared(const TensorShape &shape, uint32_t shift)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::S16);
-
-    // Create and configure function
-    NEAccumulateSquared acc;
-    acc.configure(&src, shift, &dst);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    // dst tensor filled with non-negative values
-    library->fill_tensor_uniform(NEAccessor(src), 0);
-    library->fill_tensor_uniform(NEAccessor(dst), 1, static_cast<int16_t>(0), std::numeric_limits<int16_t>::max());
-
-    // Compute function
-    acc.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(AccumulateSquared)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::xrange(0U, 16U),
-                     shape, shift)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::S16);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEAccumulateSquared acc;
-    acc.configure(&src, shift, &dst);
-
-    // Validate valid region
-    const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src.info()->valid_region(), valid_region);
-    validate(dst.info()->valid_region(), valid_region);
-
-    // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src.info()->padding(), padding);
-    validate(dst.info()->padding(), padding);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::xrange(0U, 16U),
-                     shape, shift)
-{
-    // Compute function
-    Tensor dst = compute_accumulate_squared(shape, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_accumulate_squared(shape, shift);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ 0U, 1U, 15U }),
-                     shape, shift)
-{
-    // Compute function
-    Tensor dst = compute_accumulate_squared(shape, shift);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_accumulate_squared(shape, shift);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/AccumulateWeighted.cpp b/tests/validation/NEON/AccumulateWeighted.cpp
deleted file mode 100644
index 6d45848..0000000
--- a/tests/validation/NEON/AccumulateWeighted.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/functions/NEAccumulate.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-/** Compute Neon accumulate weighted function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_accumulate_weighted(const TensorShape &shape, float alpha)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U8);
-
-    // Create and configure function
-    NEAccumulateWeighted acc;
-    acc.configure(&src, alpha, &dst);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src), 0);
-    library->fill_tensor_uniform(NEAccessor(dst), 1);
-
-    // Compute function
-    acc.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(AccumulateWeighted)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ 0.f, 0.5f, 1.f }),
-                     shape, alpha)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEAccumulateWeighted acc;
-    acc.configure(&src, alpha, &dst);
-
-    // Validate valid region
-    const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src.info()->valid_region(), valid_region);
-    validate(dst.info()->valid_region(), valid_region);
-
-    // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src.info()->padding(), padding);
-    validate(dst.info()->padding(), padding);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ 0.f, 0.5f, 1.f }),
-                     shape, alpha)
-{
-    // Compute function
-    Tensor dst = compute_accumulate_weighted(shape, alpha);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_accumulate_weighted(shape, alpha);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ 0.f, 0.5f, 1.f }),
-                     shape, alpha)
-{
-    // Compute function
-    Tensor dst = compute_accumulate_weighted(shape, alpha);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_accumulate_weighted(shape, alpha);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/ActivationLayer.cpp b/tests/validation/NEON/ActivationLayer.cpp
index da304d8..f58f3a8 100644
--- a/tests/validation/NEON/ActivationLayer.cpp
+++ b/tests/validation/NEON/ActivationLayer.cpp
@@ -21,44 +21,36 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Helpers.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEActivationLayer.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ActivationFunctionsDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ActivationLayerFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-#include <tuple>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-/** Define tolerance of the activation layer
+/** Define tolerance of the activation layer.
  *
- * @param[in] activation           The activation function used.
- * @param[in] fixed_point_position Number of bits for the fractional part..
+ * @param[in] data_type  The data type used.
+ * @param[in] activation The activation function used.
  *
  * @return Tolerance depending on the activation function.
  */
-float activation_layer_tolerance(ActivationLayerInfo::ActivationFunction activation, int fixed_point_position = 0)
+AbsoluteTolerance<float> tolerance(DataType data_type, ActivationLayerInfo::ActivationFunction activation)
 {
     switch(activation)
     {
@@ -66,152 +58,172 @@
         case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
         case ActivationLayerInfo::ActivationFunction::SQRT:
         case ActivationLayerInfo::ActivationFunction::TANH:
-            return (fixed_point_position != 0) ? 5.f : 0.00001f;
+            switch(data_type)
+            {
+                case DataType::QS8:
+                    return AbsoluteTolerance<float>(5.f);
+                case DataType::QS16:
+                    return AbsoluteTolerance<float>(11.f);
+                case DataType::F16:
+                    return AbsoluteTolerance<float>(0.01f);
+                default:
+                    return AbsoluteTolerance<float>(0.00001f);
+            }
             break;
         default:
-            return 0.f;
+            return AbsoluteTolerance<float>(0.f);
     }
 }
 
-/** Compute Neon activation layer function.
- *
- * @param[in] shape                Shape of the input and output tensors.
- * @param[in] dt                   Shape Data type of tensors.
- * @param[in] act_info             Activation layer information.
- * @param[in] fixed_point_position Number of bits for the fractional part of fixed point numbers.
- *
- * @return Computed output tensor.
- */
-Tensor compute_activation_layer(const TensorShape &shape, DataType dt, ActivationLayerInfo act_info, int fixed_point_position = 0)
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
 {
+#ifdef ARM_COMPUTE_ENABLE_FP16
+    DataType::F16,
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
+
+/** Input data sets. */
+const auto ActivationDataset = combine(combine(framework::dataset::make("InPlace", { false, true }), datasets::ActivationFunctions()), framework::dataset::make("AlphaBeta", { 0.5f, 1.f }));
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(ActivationLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), CNNDataTypes), framework::dataset::make("InPlace", { false, true })),
+               shape, data_type, in_place)
+{
+    // Set fixed point position data type allowed
+    const int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
+
     // Create tensors
-    Tensor src = create_tensor(shape, dt, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, dt, 1, fixed_point_position);
+    Tensor src = create_tensor<Tensor>(shape, data_type, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, data_type, 1, fixed_point_position);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
     NEActivationLayer act_layer;
-    act_layer.configure(&src, &dst, act_info);
 
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    if(dt == DataType::F32)
+    if(in_place)
     {
-        float min_bound = 0;
-        float max_bound = 0;
-        std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<float>(act_info.activation());
-        std::uniform_real_distribution<> distribution(min_bound, max_bound);
-        library->fill(NEAccessor(src), distribution, 0);
+        act_layer.configure(&src, nullptr, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::ABS));
     }
     else
     {
-        int min_bound = 0;
-        int max_bound = 0;
-        std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<int8_t>(act_info.activation(), fixed_point_position);
-        std::uniform_int_distribution<> distribution(min_bound, max_bound);
-        library->fill(NEAccessor(src), distribution, 0);
+        act_layer.configure(&src, &dst, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::ABS));
     }
 
-    // Compute function
-    act_layer.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(ActivationLayer)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * CNNDataTypes(), shape, dt)
-{
-    // Set fixed point position data type allowed
-    int fixed_point_position = (arm_compute::is_data_type_fixed_point(dt)) ? 3 : 0;
-
-    // Create tensors
-    Tensor src = create_tensor(shape, dt, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, dt, 1, fixed_point_position);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEActivationLayer act_layer;
-    act_layer.configure(&src, &dst, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::ABS));
-
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
     validate(src.info()->valid_region(), valid_region);
-    validate(dst.info()->valid_region(), valid_region);
+
+    if(!in_place)
+    {
+        validate(dst.info()->valid_region(), valid_region);
+    }
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src.info()->padding(), padding);
-    validate(dst.info()->padding(), padding);
+
+    if(!in_place)
+    {
+        validate(dst.info()->padding(), padding);
+    }
 }
 
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * CNNFloatDataTypes() * ActivationFunctions(), shape, dt, act_function)
+template <typename T>
+using NEActivationLayerFixture = ActivationValidationFixture<Tensor, Accessor, NEActivationLayer, T>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEActivationLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ActivationDataset),
+                                                                                                            framework::dataset::make("DataType",
+                                                                                                                    DataType::F16)))
 {
-    // Create activation layer info
-    ActivationLayerInfo act_info(act_function, 1.f, 1.f);
-
-    // Compute function
-    Tensor dst = compute_activation_layer(shape, dt, act_info);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_activation_layer(shape, dt, act_info);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, activation_layer_tolerance(act_function));
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * CNNFloatDataTypes() * ActivationFunctions(), shape, dt, act_function)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEActivationLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ActivationDataset),
+                                                                                                          framework::dataset::make("DataType",
+                                                                                                                  DataType::F16)))
 {
-    // Create activation layer info
-    ActivationLayerInfo act_info(act_function, 1.f, 1.f);
-
-    // Compute function
-    Tensor dst = compute_activation_layer(shape, dt, act_info);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_activation_layer(shape, dt, act_info);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, activation_layer_tolerance(act_function));
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
 
-/** @note We test for fixed point precision [3,5] because [1,2] and [6,7] ranges
- *        cause overflowing issues in most of the transcendentals functions.
- */
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * ActivationFunctions() * boost::unit_test::data::xrange(3, 6, 1),
-                     shape, act_function, fixed_point_position)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEActivationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ActivationDataset), framework::dataset::make("DataType",
+                                                                                                             DataType::F32)))
 {
-    // Create activation layer info
-    ActivationLayerInfo act_info(act_function, 1.f, 1.f);
-
-    // Compute function
-    Tensor dst = compute_activation_layer(shape, DataType::QS8, act_info, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_activation_layer(shape, DataType::QS8, act_info, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, activation_layer_tolerance(act_function, fixed_point_position));
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
 }
-BOOST_AUTO_TEST_SUITE_END()
+FIXTURE_DATA_TEST_CASE(RunLarge, NEActivationLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ActivationDataset), framework::dataset::make("DataType",
+                                                                                                           DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+template <typename T>
+using NEActivationLayerFixedPointFixture = ActivationValidationFixedPointFixture<Tensor, Accessor, NEActivationLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// We test for fixed point precision [3,5] because [1,2] and [6,7] ranges cause
+// overflowing issues in most of the transcendentals functions.
+FIXTURE_DATA_TEST_CASE(RunSmall, NEActivationLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ActivationDataset),
+                                                                                                                        framework::dataset::make("DataType",
+                                                                                                                                DataType::QS8)),
+                                                                                                                        framework::dataset::make("FractionalBits", 3, 6)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEActivationLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ActivationDataset),
+                                                                                                                      framework::dataset::make("DataType",
+                                                                                                                              DataType::QS8)),
+                                                                                                                      framework::dataset::make("FractionalBits", 3, 6)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 14
+FIXTURE_DATA_TEST_CASE(RunSmall, NEActivationLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ActivationDataset),
+                       framework::dataset::make("DataType",
+                                                DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEActivationLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ActivationDataset),
+                                                                                                                       framework::dataset::make("DataType",
+                                                                                                                               DataType::QS16)),
+                                                                                                                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance(_data_type, _function));
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/ArithmeticAddition.cpp b/tests/validation/NEON/ArithmeticAddition.cpp
index 5654a42..edc59a9 100644
--- a/tests/validation/NEON/ArithmeticAddition.cpp
+++ b/tests/validation/NEON/ArithmeticAddition.cpp
@@ -18,211 +18,221 @@
  * 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
+ * OUT OF OR IN CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEArithmeticAddition.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ConvertPolicyDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ArithmeticAdditionFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-/** Compute Neon arithmetic addition function.
- *
- * @param[in] shape  Shape of the input and output tensors.
- * @param[in] dt_in0 Data type of first input tensor.
- * @param[in] dt_in1 Data type of second input tensor.
- * @param[in] dt_out Data type of the output tensor.
- * @param[in] policy Overflow policy of the operation.
- *
- * @return Computed output tensor.
- */
-Tensor compute_arithmetic_addition(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy policy)
+/** Input data sets **/
+const auto ArithmeticAdditionU8Dataset = combine(combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::U8)), framework::dataset::make("DataType",
+                                                 DataType::U8));
+const auto ArithmeticAdditionS16Dataset = combine(combine(framework::dataset::make("DataType", { DataType::U8, DataType::S16 }), framework::dataset::make("DataType", DataType::S16)),
+                                                  framework::dataset::make("DataType", DataType::S16));
+const auto ArithmeticAdditionQS8Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS8), framework::dataset::make("DataType", DataType::QS8)),
+                                                  framework::dataset::make("DataType", DataType::QS8));
+const auto ArithmeticAdditionQS16Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS16), framework::dataset::make("DataType", DataType::QS16)),
+                                                   framework::dataset::make("DataType", DataType::QS16));
+#ifdef ARM_COMPUTE_ENABLE_FP16
+const auto ArithmeticAdditionFP16Dataset = combine(combine(framework::dataset::make("DataType", DataType::F16), framework::dataset::make("DataType", DataType::F16)),
+                                                   framework::dataset::make("DataType", DataType::F16));
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+const auto ArithmeticAdditionFP32Dataset = combine(combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::F32)),
+                                                   framework::dataset::make("DataType", DataType::F32));
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(ArithmeticAddition)
+
+template <typename T>
+using NEArithmeticAdditionFixture = ArithmeticAdditionValidationFixture<Tensor, Accessor, NEArithmeticAddition, T>;
+
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, dt_in0);
-    Tensor src2 = create_tensor(shape, dt_in1);
-    Tensor dst  = create_tensor(shape, dt_out);
+    Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::U8);
+    Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::U8);
+    Tensor dst      = create_tensor<Tensor>(shape, DataType::U8);
 
-    // Create and configure function
+    // Create and Configure function
     NEArithmeticAddition add;
-    add.configure(&src1, &src2, &dst, policy);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-    library->fill_tensor_uniform(NEAccessor(src2), 1);
-
-    // Compute function
-    add.run();
-
-    return dst;
-}
-
-void validate_configuration(const Tensor &src1, const Tensor &src2, Tensor &dst, TensorShape shape, ConvertPolicy policy)
-{
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEArithmeticAddition add;
-    add.configure(&src1, &src2, &dst, policy);
+    add.configure(&ref_src1, &ref_src2, &dst, policy);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src1.info()->valid_region(), valid_region);
-    validate(src2.info()->valid_region(), valid_region);
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src1.info()->padding(), padding);
-    validate(src2.info()->padding(), padding);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
-} // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(ArithmeticAddition)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionU8Dataset),
+                                                                                                                  framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
+TEST_SUITE(S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
+                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, data_type, policy)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
+    Tensor ref_src1 = create_tensor<Tensor>(shape, data_type);
+    Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::S16);
+    Tensor dst      = create_tensor<Tensor>(shape, DataType::S16);
 
-    validate_configuration(src1, src2, dst, shape, policy);
+    // Create and Configure function
+    NEArithmeticAddition add;
+    add.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionS16Dataset),
+                                                                                                                  framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
 {
-    // Compute function
-    Tensor dst = compute_arithmetic_addition(shape, DataType::U8, DataType::U8, DataType::U8, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_addition(shape, DataType::U8, DataType::U8, DataType::U8, policy);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(S16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, dt, policy)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticAdditionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticAdditionS16Dataset),
+                                                                                                                framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+template <typename T>
+using NEArithmeticAdditionFixedPointFixture = ArithmeticAdditionValidationFixedPointFixture<Tensor, Accessor, NEArithmeticAddition, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ArithmeticAdditionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticAdditionFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticAdditionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ArithmeticAdditionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticAdditionFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticAdditionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(F16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<half>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), ArithmeticAdditionFP16Dataset),
+                                                                                                         framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+
+TEST_SUITE(F32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, dt);
-    Tensor src2 = create_tensor(shape, DataType::S16);
-    Tensor dst  = create_tensor(shape, DataType::S16);
+    Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::F32);
+    Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::F32);
+    Tensor dst      = create_tensor<Tensor>(shape, DataType::F32);
 
-    validate_configuration(src1, src2, dst, shape, policy);
+    // Create and Configure function
+    NEArithmeticAddition add;
+    add.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, dt, policy)
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticAdditionFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticAdditionFP32Dataset),
+                                                                                                                framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
 {
-    // Compute function
-    Tensor dst = compute_arithmetic_addition(shape, dt, DataType::S16, DataType::S16, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_addition(shape, dt, DataType::S16, DataType::S16, policy);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, dt, policy)
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticAdditionFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticAdditionFP32Dataset),
+                                                                                                              framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
 {
-    // Compute function
-    Tensor dst = compute_arithmetic_addition(shape, dt, DataType::S16, DataType::S16, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_addition(shape, dt, DataType::S16, DataType::S16, policy);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(F32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::F32);
-    Tensor src2 = create_tensor(shape, DataType::F32);
-    Tensor dst  = create_tensor(shape, DataType::F32);
-
-    validate_configuration(src1, src2, dst, shape, policy);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
-{
-    // Compute function
-    Tensor dst = compute_arithmetic_addition(shape, DataType::F32, DataType::F32, DataType::F32, ConvertPolicy::WRAP);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_addition(shape, DataType::F32, DataType::F32, DataType::F32, ConvertPolicy::WRAP);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
-{
-    // Compute function
-    Tensor dst = compute_arithmetic_addition(shape, DataType::F32, DataType::F32, DataType::F32, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_addition(shape, DataType::F32, DataType::F32, DataType::F32, policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/ArithmeticSubtraction.cpp b/tests/validation/NEON/ArithmeticSubtraction.cpp
index 9c0e913..3d184f1 100644
--- a/tests/validation/NEON/ArithmeticSubtraction.cpp
+++ b/tests/validation/NEON/ArithmeticSubtraction.cpp
@@ -18,211 +18,223 @@
  * 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
+ * OUT OF OR IN CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEArithmeticSubtraction.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ConvertPolicyDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ArithmeticSubtractionFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-/** Compute Neon arithmetic subtraction function.
- *
- * @param[in] shape  Shape of the input and output tensors.
- * @param[in] dt_in0 Data type of first input tensor.
- * @param[in] dt_in1 Data type of second input tensor.
- * @param[in] dt_out Data type of the output tensor.
- * @param[in] policy Overflow policy of the operation.
- *
- * @return Computed output tensor.
- */
-Tensor compute_arithmetic_subtraction(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy policy)
+/** Input data sets **/
+const auto ArithmeticSubtractionU8Dataset = combine(combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::U8)),
+                                                    framework::dataset::make("DataType",
+                                                                             DataType::U8));
+const auto ArithmeticSubtractionS16Dataset = combine(combine(framework::dataset::make("DataType", { DataType::U8, DataType::S16 }), framework::dataset::make("DataType", DataType::S16)),
+                                                     framework::dataset::make("DataType", DataType::S16));
+const auto ArithmeticSubtractionQS8Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS8), framework::dataset::make("DataType", DataType::QS8)),
+                                                     framework::dataset::make("DataType", DataType::QS8));
+const auto ArithmeticSubtractionQS16Dataset = combine(combine(framework::dataset::make("DataType", DataType::QS16), framework::dataset::make("DataType", DataType::QS16)),
+                                                      framework::dataset::make("DataType", DataType::QS16));
+#ifdef ARM_COMPUTE_ENABLE_FP16
+const auto ArithmeticSubtractionFP16Dataset = combine(combine(framework::dataset::make("DataType", DataType::F16), framework::dataset::make("DataType", DataType::F16)),
+                                                      framework::dataset::make("DataType", DataType::F16));
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+const auto ArithmeticSubtractionFP32Dataset = combine(combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::F32)),
+                                                      framework::dataset::make("DataType", DataType::F32));
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(ArithmeticSubtraction)
+
+template <typename T>
+using NEArithmeticSubtractionFixture = ArithmeticSubtractionValidationFixture<Tensor, Accessor, NEArithmeticSubtraction, T>;
+
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, dt_in0);
-    Tensor src2 = create_tensor(shape, dt_in1);
-    Tensor dst  = create_tensor(shape, dt_out);
+    Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::U8);
+    Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::U8);
+    Tensor dst      = create_tensor<Tensor>(shape, DataType::U8);
 
-    // Create and configure function
+    // Create and Configure function
     NEArithmeticSubtraction sub;
-    sub.configure(&src1, &src2, &dst, policy);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-    library->fill_tensor_uniform(NEAccessor(src2), 1);
-
-    // Compute function
-    sub.run();
-
-    return dst;
-}
-
-void validate_configuration(const Tensor &src1, const Tensor &src2, Tensor &dst, TensorShape shape, ConvertPolicy policy)
-{
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEArithmeticSubtraction sub;
-    sub.configure(&src1, &src2, &dst, policy);
+    sub.configure(&ref_src1, &ref_src2, &dst, policy);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src1.info()->valid_region(), valid_region);
-    validate(src2.info()->valid_region(), valid_region);
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src1.info()->padding(), padding);
-    validate(src2.info()->padding(), padding);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
-} // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(ArithmeticSubtraction)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticSubtractionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionU8Dataset),
+                                                                                                                     framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
+TEST_SUITE(S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
+                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, data_type, policy)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
+    Tensor ref_src1 = create_tensor<Tensor>(shape, data_type);
+    Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::S16);
+    Tensor dst      = create_tensor<Tensor>(shape, DataType::S16);
 
-    validate_configuration(src1, src2, dst, shape, policy);
+    // Create and Configure function
+    NEArithmeticSubtraction sub;
+    sub.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticSubtractionFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionS16Dataset),
+                                                                                                                     framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
 {
-    // Compute function
-    Tensor dst = compute_arithmetic_subtraction(shape, DataType::U8, DataType::U8, DataType::U8, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_subtraction(shape, DataType::U8, DataType::U8, DataType::U8, policy);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(S16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, dt, policy)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticSubtractionFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticSubtractionS16Dataset),
+                                                                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+template <typename T>
+using NEArithmeticSubtractionFixedPointFixture = ArithmeticSubtractionValidationFixedPointFixture<Tensor, Accessor, NEArithmeticSubtraction, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticSubtractionFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), ArithmeticSubtractionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticSubtractionFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticSubtractionQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticSubtractionFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(),
+                       ArithmeticSubtractionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticSubtractionFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), ArithmeticSubtractionQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       framework::dataset::make("FractionalBits", 1, 15)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticSubtractionFixture<half>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionFP16Dataset),
+                                                                                                            framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+
+TEST_SUITE(FP32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+               shape, policy)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, dt);
-    Tensor src2 = create_tensor(shape, DataType::S16);
-    Tensor dst  = create_tensor(shape, DataType::S16);
+    Tensor ref_src1 = create_tensor<Tensor>(shape, DataType::F32);
+    Tensor ref_src2 = create_tensor<Tensor>(shape, DataType::F32);
+    Tensor dst      = create_tensor<Tensor>(shape, DataType::F32);
 
-    validate_configuration(src1, src2, dst, shape, policy);
+    // Create and Configure function
+    NEArithmeticSubtraction sub;
+    sub.configure(&ref_src1, &ref_src2, &dst, policy);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(ref_src1.info()->padding(), padding);
+    validate(ref_src2.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, dt, policy)
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEArithmeticSubtractionFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), ArithmeticSubtractionFP32Dataset),
+                                                                                                                   framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
 {
-    // Compute function
-    Tensor dst = compute_arithmetic_subtraction(shape, dt, DataType::S16, DataType::S16, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_subtraction(shape, dt, DataType::S16, DataType::S16, policy);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, dt, policy)
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEArithmeticSubtractionFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), ArithmeticSubtractionFP32Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })))
 {
-    // Compute function
-    Tensor dst = compute_arithmetic_subtraction(shape, dt, DataType::S16, DataType::S16, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_subtraction(shape, dt, DataType::S16, DataType::S16, policy);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(F32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::F32);
-    Tensor src2 = create_tensor(shape, DataType::F32);
-    Tensor dst  = create_tensor(shape, DataType::F32);
-
-    validate_configuration(src1, src2, dst, shape, policy);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
-{
-    // Compute function
-    Tensor dst = compute_arithmetic_subtraction(shape, DataType::F32, DataType::F32, DataType::F32, ConvertPolicy::WRAP);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_subtraction(shape, DataType::F32, DataType::F32, DataType::F32, ConvertPolicy::WRAP);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }),
-                     shape, policy)
-{
-    // Compute function
-    Tensor dst = compute_arithmetic_subtraction(shape, DataType::F32, DataType::F32, DataType::F32, policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_arithmetic_subtraction(shape, DataType::F32, DataType::F32, DataType::F32, policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/BatchNormalizationLayer.cpp b/tests/validation/NEON/BatchNormalizationLayer.cpp
index 7656b2f..9ca26eb 100644
--- a/tests/validation/NEON/BatchNormalizationLayer.cpp
+++ b/tests/validation/NEON/BatchNormalizationLayer.cpp
@@ -21,175 +21,113 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TypePrinter.h"
-#include "dataset/BatchNormalizationLayerDataset.h"
-#include "tests/validation/Helpers.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
+#include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEBatchNormalizationLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/RandomBatchNormalizationLayerDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BatchNormalizationLayerFixture.h"
 
-#include <random>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-const float tolerance_f = 1e-05; /**< Tolerance value for comparing reference's output against floating point implementation's output */
-const float tolerance_q = 3;     /**< Tolerance value for comparing reference's output against quantized implementation's output */
-
-/** Compute Neon batch normalization function.
- *
- * @param[in] shape     Shape of the input and output tensors.
- * @param[in] dt        Data type of input and output tensors.
- * @param[in] norm_info Normalization Layer information.
- *
- * @return Computed output tensor.
- */
-Tensor compute_reference_batch_normalization_layer(const TensorShape &shape0, const TensorShape &shape1, DataType dt, float epsilon, int fixed_point_position = 0)
-{
-    // Create tensors
-    Tensor src   = create_tensor(shape0, dt, 1, fixed_point_position);
-    Tensor dst   = create_tensor(shape0, dt, 1, fixed_point_position);
-    Tensor mean  = create_tensor(shape1, dt, 1, fixed_point_position);
-    Tensor var   = create_tensor(shape1, dt, 1, fixed_point_position);
-    Tensor beta  = create_tensor(shape1, dt, 1, fixed_point_position);
-    Tensor gamma = create_tensor(shape1, dt, 1, fixed_point_position);
-
-    // Create and configure function
-    NEBatchNormalizationLayer norm;
-    norm.configure(&src, &dst, &mean, &var, &beta, &gamma, epsilon);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-    mean.allocator()->allocate();
-    var.allocator()->allocate();
-    beta.allocator()->allocate();
-    gamma.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-    BOOST_TEST(!mean.info()->is_resizable());
-    BOOST_TEST(!var.info()->is_resizable());
-    BOOST_TEST(!beta.info()->is_resizable());
-    BOOST_TEST(!gamma.info()->is_resizable());
-
-    // Fill tensors
-    if(dt == DataType::F32)
-    {
-        float min_bound = 0.f;
-        float max_bound = 0.f;
-        std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<float>();
-        std::uniform_real_distribution<> distribution(min_bound, max_bound);
-        std::uniform_real_distribution<> distribution_var(0, max_bound);
-        library->fill(NEAccessor(src), distribution, 0);
-        library->fill(NEAccessor(mean), distribution, 1);
-        library->fill(NEAccessor(var), distribution_var, 0);
-        library->fill(NEAccessor(beta), distribution, 3);
-        library->fill(NEAccessor(gamma), distribution, 4);
-    }
-    else
-    {
-        int min_bound = 0;
-        int max_bound = 0;
-        std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<int8_t>(fixed_point_position);
-        std::uniform_int_distribution<> distribution(min_bound, max_bound);
-        std::uniform_int_distribution<> distribution_var(0, max_bound);
-        library->fill(NEAccessor(src), distribution, 0);
-        library->fill(NEAccessor(mean), distribution, 1);
-        library->fill(NEAccessor(var), distribution_var, 0);
-        library->fill(NEAccessor(beta), distribution, 3);
-        library->fill(NEAccessor(gamma), distribution, 4);
-    }
-
-    // Compute function
-    norm.run();
-
-    return dst;
-}
+constexpr AbsoluteTolerance<float> tolerance_f32(0.00001f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
+#ifdef ARM_COMPUTE_ENABLE_FP16
+constexpr AbsoluteTolerance<float> tolerance_f16(0.01f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F16 */
+#endif                                                   /* ARM_COMPUTE_ENABLE_FP16 */
+constexpr AbsoluteTolerance<float> tolerance_qs8(3.0f);  /**< Tolerance value for comparing reference's output against implementation's output for DataType::QS8 */
+constexpr AbsoluteTolerance<float> tolerance_qs16(6.0f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::QS16 */
 } // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(BatchNormalizationLayer)
+TEST_SUITE(NEON)
+TEST_SUITE(BatchNormalizationLayer)
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, RandomBatchNormalizationLayerDataset() * (boost::unit_test::data::make(DataType::F32) + boost::unit_test::data::make(DataType::QS8)), obj, dt)
+template <typename T>
+using NEBatchNormalizationLayerFixture = BatchNormalizationLayerValidationFixture<Tensor, Accessor, NEBatchNormalizationLayer, T>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(datasets::RandomBatchNormalizationLayerDataset(), framework::dataset::make("DataType", { DataType::QS8, DataType::QS16, DataType::F32 })),
+               shape0, shape1, epsilon, dt)
 {
     // Set fixed point position data type allowed
     int fixed_point_position = (arm_compute::is_data_type_fixed_point(dt)) ? 3 : 0;
 
     // Create tensors
-    Tensor src   = create_tensor(obj.shape0, dt, 1, fixed_point_position);
-    Tensor dst   = create_tensor(obj.shape0, dt, 1, fixed_point_position);
-    Tensor mean  = create_tensor(obj.shape1, dt, 1, fixed_point_position);
-    Tensor var   = create_tensor(obj.shape1, dt, 1, fixed_point_position);
-    Tensor beta  = create_tensor(obj.shape1, dt, 1, fixed_point_position);
-    Tensor gamma = create_tensor(obj.shape1, dt, 1, fixed_point_position);
+    Tensor src   = create_tensor<Tensor>(shape0, dt, 1, fixed_point_position);
+    Tensor dst   = create_tensor<Tensor>(shape0, dt, 1, fixed_point_position);
+    Tensor mean  = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
+    Tensor var   = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
+    Tensor beta  = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
+    Tensor gamma = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
 
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-    BOOST_TEST(mean.info()->is_resizable());
-    BOOST_TEST(var.info()->is_resizable());
-    BOOST_TEST(beta.info()->is_resizable());
-    BOOST_TEST(gamma.info()->is_resizable());
-
-    // Create and configure function
+    // Create and Configure function
     NEBatchNormalizationLayer norm;
-    norm.configure(&src, &dst, &mean, &var, &beta, &gamma, obj.epsilon);
+    norm.configure(&src, &dst, &mean, &var, &beta, &gamma, epsilon);
 
     // Validate valid region
-    const ValidRegion valid_region     = shape_to_valid_region(obj.shape0);
-    const ValidRegion valid_region_vec = shape_to_valid_region(obj.shape1);
-    validate(src.info()->valid_region(), valid_region);
+    const ValidRegion valid_region = shape_to_valid_region(shape0);
     validate(dst.info()->valid_region(), valid_region);
-    validate(mean.info()->valid_region(), valid_region_vec);
-    validate(var.info()->valid_region(), valid_region_vec);
-    validate(beta.info()->valid_region(), valid_region_vec);
-    validate(gamma.info()->valid_region(), valid_region_vec);
 }
 
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(Random,
-                     RandomBatchNormalizationLayerDataset() * boost::unit_test::data::make(DataType::F32),
-                     obj, dt)
+TEST_SUITE(Float)
+FIXTURE_DATA_TEST_CASE(Random, NEBatchNormalizationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::RandomBatchNormalizationLayerDataset(),
+                                                                                                                   framework::dataset::make("DataType", DataType::F32)))
 {
-    // Compute function
-    Tensor dst = compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f, 0);
+    validate(Accessor(_target), _reference, tolerance_f32, 0);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(Random,
-                     RandomBatchNormalizationLayerDataset() * boost::unit_test::data::make(DataType::QS8) * boost::unit_test::data::xrange(1, 6),
-                     obj, dt, fixed_point_position)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(Float16)
+FIXTURE_DATA_TEST_CASE(Random, NEBatchNormalizationLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(datasets::RandomBatchNormalizationLayerDataset(),
+                                                                                                                  framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute function
-    Tensor dst = compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_q, 0);
+    validate(Accessor(_target), _reference, tolerance_f16, 0);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE(Quantized)
+template <typename T>
+using NEBatchNormalizationLayerFixedPointFixture = BatchNormalizationLayerValidationFixedPointFixture<Tensor, Accessor, NEBatchNormalizationLayer, T>;
+
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(Random, NEBatchNormalizationLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::RandomBatchNormalizationLayerDataset(),
+                       framework::dataset::make("DataType", DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs8, 0);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(Random, NEBatchNormalizationLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::RandomBatchNormalizationLayerDataset(),
+                       framework::dataset::make("DataType", DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs16, 0);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/BitwiseAnd.cpp b/tests/validation/NEON/BitwiseAnd.cpp
index 8c0eda9..179413e 100644
--- a/tests/validation/NEON/BitwiseAnd.cpp
+++ b/tests/validation/NEON/BitwiseAnd.cpp
@@ -21,142 +21,42 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEBitwiseAnd.h"
-#include "arm_compute/runtime/SubTensor.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseAndFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Neon bitwise and function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_bitwise_and(const TensorShape &shape)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(BitwiseAnd)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
+    Tensor src1 = create_tensor<Tensor>(shape, data_type);
+    Tensor src2 = create_tensor<Tensor>(shape, data_type);
+    Tensor dst  = create_tensor<Tensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
-    NEBitwiseAnd band;
-    band.configure(&src1, &src2, &dst);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-    library->fill_tensor_uniform(NEAccessor(src2), 1);
-
-    // Compute function
-    band.run();
-
-    return dst;
-}
-
-/** Compute Neon bitwise and function that splits the input and output in two subtensor.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_bitwise_and_subtensor(const TensorShape &shape)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    // Create SubTensors
-    int         coord_z   = shape.z() / 2;
-    TensorShape sub_shape = shape;
-    sub_shape.set(2, coord_z);
-
-    SubTensor src1_sub1(&src1, sub_shape, Coordinates());
-    SubTensor src1_sub2(&src1, sub_shape, Coordinates(0, 0, coord_z));
-    SubTensor src2_sub1(&src2, sub_shape, Coordinates());
-    SubTensor src2_sub2(&src2, sub_shape, Coordinates(0, 0, coord_z));
-    SubTensor dst_sub1(&dst, sub_shape, Coordinates());
-    SubTensor dst_sub2(&dst, sub_shape, Coordinates(0, 0, coord_z));
-
-    // Create and configure function
-    NEBitwiseAnd band1, band2;
-    band1.configure(&src1_sub1, &src2_sub1, &dst_sub1);
-    band2.configure(&src1_sub2, &src2_sub2, &dst_sub2);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    std::uniform_int_distribution<> distribution(0, 255);
-    library->fill(NEAccessor(src1), distribution, 0);
-    library->fill(NEAccessor(src2), distribution, 1);
-
-    // Compute function
-    band1.run();
-    band2.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(BitwiseAnd)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, SmallShapes() + LargeShapes(), shape)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEBitwiseAnd band;
-    band.configure(&src1, &src2, &dst);
+    NEBitwiseAnd bitwise_and;
+    bitwise_and.configure(&src1, &src2, &dst);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
@@ -165,54 +65,30 @@
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src1.info()->padding(), padding);
     validate(src2.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
+template <typename T>
+using NEBitwiseAndFixture = BitwiseAndValidationFixture<Tensor, Accessor, NEBitwiseAnd, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEBitwiseAndFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
 {
-    // Compute function
-    Tensor dst = compute_bitwise_and(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_and(shape);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEBitwiseAndFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_AUTO_TEST_CASE(RunSubTensor)
-{
-    // Create shape
-    TensorShape shape(27U, 35U, 8U, 2U);
-
-    // Compute function
-    Tensor dst = compute_bitwise_and_subtensor(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_and(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(), shape)
-{
-    // Compute function
-    Tensor dst = compute_bitwise_and(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_and(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/BitwiseNot.cpp b/tests/validation/NEON/BitwiseNot.cpp
index cb0a1fd..c438a57 100644
--- a/tests/validation/NEON/BitwiseNot.cpp
+++ b/tests/validation/NEON/BitwiseNot.cpp
@@ -21,84 +21,40 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEBitwiseNot.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseNotFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Neon bitwise not function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_bitwise_not(const TensorShape &shape)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(BitwiseNot)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
 {
     // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U8);
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, data_type);
 
-    // Create not configure function
-    NEBitwiseNot bnot;
-    bnot.configure(&src, &dst);
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src), 0);
-
-    // Compute function
-    bnot.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(BitwiseNot)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, SmallShapes() + LargeShapes(), shape)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create not configure function
-    NEBitwiseNot bnot;
-    bnot.configure(&src, &dst);
+    // Create and configure function
+    NEBitwiseNot bitwise_not;
+    bitwise_not.configure(&src, &dst);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
@@ -106,37 +62,29 @@
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
+template <typename T>
+using NEBitwiseNotFixture = BitwiseNotValidationFixture<Tensor, Accessor, NEBitwiseNot, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEBitwiseNotFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
 {
-    // Compute function
-    Tensor dst = compute_bitwise_not(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_not(shape);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEBitwiseNotFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(), shape)
-{
-    // Compute function
-    Tensor dst = compute_bitwise_not(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_not(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/BitwiseOr.cpp b/tests/validation/NEON/BitwiseOr.cpp
index cb853d3..0e4cdbe 100644
--- a/tests/validation/NEON/BitwiseOr.cpp
+++ b/tests/validation/NEON/BitwiseOr.cpp
@@ -21,90 +21,42 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEBitwiseOr.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseOrFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Neon bitwise Or function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_bitwise_or(const TensorShape &shape)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(BitwiseOr)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
+    Tensor src1 = create_tensor<Tensor>(shape, data_type);
+    Tensor src2 = create_tensor<Tensor>(shape, data_type);
+    Tensor dst  = create_tensor<Tensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
-    NEBitwiseOr bor;
-    bor.configure(&src1, &src2, &dst);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-    library->fill_tensor_uniform(NEAccessor(src2), 1);
-
-    // Compute function
-    bor.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(BitwiseOr)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, SmallShapes() + LargeShapes(), shape)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEBitwiseOr bor;
-    bor.configure(&src1, &src2, &dst);
+    NEBitwiseOr bitwise_or;
+    bitwise_or.configure(&src1, &src2, &dst);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
@@ -113,38 +65,30 @@
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src1.info()->padding(), padding);
     validate(src2.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
+template <typename T>
+using NEBitwiseOrFixture = BitwiseOrValidationFixture<Tensor, Accessor, NEBitwiseOr, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEBitwiseOrFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                         DataType::U8)))
 {
-    // Compute function
-    Tensor dst = compute_bitwise_or(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_or(shape);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEBitwiseOrFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                       DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(), shape)
-{
-    // Compute function
-    Tensor dst = compute_bitwise_or(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_or(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/BitwiseXor.cpp b/tests/validation/NEON/BitwiseXor.cpp
index 1715b04..70363c0 100644
--- a/tests/validation/NEON/BitwiseXor.cpp
+++ b/tests/validation/NEON/BitwiseXor.cpp
@@ -21,90 +21,42 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEBitwiseXor.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/BitwiseXorFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Neon bitwise xor function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_bitwise_xor(const TensorShape &shape)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(BitwiseXor)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
+    Tensor src1 = create_tensor<Tensor>(shape, data_type);
+    Tensor src2 = create_tensor<Tensor>(shape, data_type);
+    Tensor dst  = create_tensor<Tensor>(shape, data_type);
 
-    // Create xor configure function
-    NEBitwiseXor bxor;
-    bxor.configure(&src1, &src2, &dst);
+    ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-    library->fill_tensor_uniform(NEAccessor(src2), 1);
-
-    // Compute function
-    bxor.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(BitwiseXor)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, SmallShapes() + LargeShapes(), shape)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create xor configure function
-    NEBitwiseXor bxor;
-    bxor.configure(&src1, &src2, &dst);
+    // Create and configure function
+    NEBitwiseXor bitwise_xor;
+    bitwise_xor.configure(&src1, &src2, &dst);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
@@ -113,38 +65,30 @@
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src1.info()->padding(), padding);
     validate(src2.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
+template <typename T>
+using NEBitwiseXorFixture = BitwiseXorValidationFixture<Tensor, Accessor, NEBitwiseXor, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEBitwiseXorFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
 {
-    // Compute function
-    Tensor dst = compute_bitwise_xor(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_xor(shape);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEBitwiseXorFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(), shape)
-{
-    // Compute function
-    Tensor dst = compute_bitwise_xor(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_bitwise_xor(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/Box3x3.cpp b/tests/validation/NEON/Box3x3.cpp
index 5da015c..5f2e827 100644
--- a/tests/validation/NEON/Box3x3.cpp
+++ b/tests/validation/NEON/Box3x3.cpp
@@ -21,125 +21,90 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEBox3x3.h"
-#include "arm_compute/runtime/SubTensor.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/Box3x3Fixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-/** Compute Neon 3-by-3 box filter.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_box3x3(const TensorShape &shape)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U8);
-
-    // Create and configure function
-    NEBox3x3 band;
-    band.configure(&src, &dst, BorderMode::UNDEFINED);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src), 0);
-
-    // Compute function
-    band.run();
-
-    return dst;
-}
+constexpr unsigned int filter_size = 3;              /* Size of the kernel/filter in number of elements. */
+constexpr BorderSize   border_size(filter_size / 2); /* Border size of the kernel/filter around its central element. */
 } // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(Box3x3)
+TEST_SUITE(NEON)
+TEST_SUITE(Box3x3)
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, SmallShapes() + LargeShapes(), shape)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+                                                                   datasets::BorderModes()),
+               shape, data_type, border_mode)
 {
     // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U8);
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, data_type);
 
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
-    NEBox3x3 band;
-    band.configure(&src, &dst, BorderMode::UNDEFINED);
+    NEBox3x3 box3x3;
+    box3x3.configure(&src, &dst, border_mode);
 
     // Validate valid region
-    const ValidRegion src_valid_region = shape_to_valid_region(shape);
-    const ValidRegion dst_valid_region = shape_to_valid_region_undefined_border(shape, BorderSize(1));
-    validate(src.info()->valid_region(), src_valid_region);
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size);
     validate(dst.info()->valid_region(), dst_valid_region);
 
     // Validate padding
-    const PaddingSize read_padding(0, required_padding_undefined_border_read(shape.x(), 16, 8), 0, 0);
-    const PaddingSize write_padding(0, required_padding_undefined_border_write(shape.x(), 8, 1), 0, 0);
-    validate(src.info()->padding(), read_padding);
-    validate(dst.info()->padding(), write_padding);
+    PaddingCalculator calculator(shape.x(), 8);
+    calculator.set_border_size(1);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-1);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst.info()->padding(), dst_padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
+template <typename T>
+using NEBox3x3Fixture = Box3x3ValidationFixture<Tensor, Accessor, NEBox3x3, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEBox3x3Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                              DataType::U8)),
+                                                                                                      datasets::BorderModes()))
 {
-    // Compute function
-    Tensor dst = compute_box3x3(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_box3x3(shape);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, shape_to_valid_region_undefined_border(shape, BorderSize(1)));
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(), shape)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEBox3x3Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::U8)),
+                                                                                                    datasets::BorderModes()))
 {
-    // Compute function
-    Tensor dst = compute_box3x3(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_box3x3(shape);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, shape_to_valid_region_undefined_border(shape, BorderSize(1)));
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
 }
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/ConvolutionLayer.cpp b/tests/validation/NEON/ConvolutionLayer.cpp
index a1dbe38..944c506 100644
--- a/tests/validation/NEON/ConvolutionLayer.cpp
+++ b/tests/validation/NEON/ConvolutionLayer.cpp
@@ -21,108 +21,75 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TypePrinter.h"
-#include "dataset/ConvolutionLayerDataset.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Error.h"
+#include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEConvolutionLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/LargeConvolutionLayerDataset.h"
+#include "tests/datasets/SmallConvolutionLayerDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ConvolutionLayerFixture.h"
 
-#include <random>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-const float tolerance_f32 = 1e-03f; /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
-const float tolerance_qs8 = 3.0f;   /**< Tolerance value for comparing reference's output against implementation's output for DataType::QS8 */
+const AbsoluteTolerance<float> tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
+#ifdef ARM_COMPUTE_ENABLE_FP16
+const AbsoluteTolerance<float> tolerance_f16(0.01f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F16 */
+#endif                                               /* ARM_COMPUTE_ENABLE_FP16 */
+const AbsoluteTolerance<float> tolerance_q(1.0f);    /**< Tolerance value for comparing reference's output against implementation's output for fixed point data types */
 
-Tensor compute_convolution_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, DataType dt,
-                                 const PadStrideInfo &conv_info, int fixed_point_position)
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
 {
-    // Create tensors
-    Tensor src     = create_tensor(input_shape, dt, 1, fixed_point_position);
-    Tensor weights = create_tensor(weights_shape, dt, 1, fixed_point_position);
-    Tensor bias    = create_tensor(bias_shape, dt, 1, fixed_point_position);
-    Tensor dst     = create_tensor(output_shape, dt, 1, fixed_point_position);
-
-    // Create and configure function
-    NEConvolutionLayer conv;
-    conv.configure(&src, &weights, &bias, &dst, conv_info);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    weights.allocator()->allocate();
-    bias.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!weights.info()->is_resizable());
-    BOOST_TEST(!bias.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    if(dt == DataType::F32)
-    {
-        std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
-        library->fill(NEAccessor(src), distribution, 0);
-        library->fill(NEAccessor(weights), distribution, 1);
-        library->fill(NEAccessor(bias), distribution, 2);
-    }
-    else
-    {
-        library->fill_tensor_uniform(NEAccessor(src), 0);
-        library->fill_tensor_uniform(NEAccessor(weights), 1);
-        library->fill_tensor_uniform(NEAccessor(bias), 2);
-    }
-
-    // Compute NEConvolutionLayer function
-    conv.run();
-
-    return dst;
-}
+#ifdef ARM_COMPUTE_ENABLE_FP16
+    DataType::F16,
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
 } // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(ConvolutionLayer)
-BOOST_AUTO_TEST_SUITE(GEMM)
+TEST_SUITE(NEON)
+TEST_SUITE(ConvolutionLayer)
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration,
-                     AlexNetConvolutionLayerDataset() * boost::unit_test::data::make({ DataType::F32, DataType::QS8 }),
-                     conv_set, dt)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallConvolutionLayerDataset(), datasets::LargeConvolutionLayerDataset()), CNNDataTypes),
+               input_shape, weights_shape, bias_shape, output_shape, info, data_type)
 {
     // Set fixed point position data type allowed
-    int fixed_point_position = (dt == DataType::F32) ? 0 : 3;
+    int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
 
     // Create tensors
-    Tensor src     = create_tensor(conv_set.src_shape, dt, 1, fixed_point_position);
-    Tensor weights = create_tensor(conv_set.weights_shape, dt, 1, fixed_point_position);
-    Tensor bias    = create_tensor(conv_set.bias_shape, dt, 1, fixed_point_position);
-    Tensor dst     = create_tensor(conv_set.dst_shape, dt, 1, fixed_point_position);
+    Tensor src     = create_tensor<Tensor>(input_shape, data_type, 1, fixed_point_position);
+    Tensor weights = create_tensor<Tensor>(weights_shape, data_type, 1, fixed_point_position);
+    Tensor bias    = create_tensor<Tensor>(bias_shape, data_type, 1, fixed_point_position);
+    Tensor dst     = create_tensor<Tensor>(output_shape, data_type, 1, fixed_point_position);
 
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(weights.info()->is_resizable());
-    BOOST_TEST(bias.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
     NEConvolutionLayer conv;
-    conv.configure(&src, &weights, &bias, &dst, conv_set.info);
+    conv.configure(&src, &weights, &bias, &dst, info);
 
     // Validate valid region
-    const ValidRegion src_valid_region     = shape_to_valid_region(conv_set.src_shape);
-    const ValidRegion weights_valid_region = shape_to_valid_region(conv_set.weights_shape);
-    const ValidRegion bias_valid_region    = shape_to_valid_region(conv_set.bias_shape);
-    const ValidRegion dst_valid_region     = shape_to_valid_region(conv_set.dst_shape);
+    const ValidRegion src_valid_region     = shape_to_valid_region(input_shape);
+    const ValidRegion weights_valid_region = shape_to_valid_region(weights_shape);
+    const ValidRegion bias_valid_region    = shape_to_valid_region(bias_shape);
+    const ValidRegion dst_valid_region     = shape_to_valid_region(output_shape);
 
     validate(src.info()->valid_region(), src_valid_region);
     validate(weights.info()->valid_region(), weights_valid_region);
@@ -130,71 +97,94 @@
     validate(dst.info()->valid_region(), dst_valid_region);
 }
 
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(SmallConvolutionLayer,
-                     SmallConvolutionLayerDataset() * boost::unit_test::data::make(DataType::F32),
-                     conv_set, dt)
+template <typename T>
+using NEConvolutionLayerFixture = ConvolutionValidationFixture<Tensor, Accessor, NEConvolutionLayer, T>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallConvolutionLayerDataset(),
+                                                                                                                     framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                             framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute function
-    Tensor dst = compute_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f32);
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(LargeConvolutionLayer,
-                     AlexNetConvolutionLayerDataset() * boost::unit_test::data::make(DataType::F32),
-                     conv_set, dt)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                   framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                           framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute function
-    Tensor dst = compute_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f32);
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
 
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(SmallConvolutionLayer,
-                     SmallConvolutionLayerDataset() * boost::unit_test::data::make(DataType::QS8) * boost::unit_test::data::xrange(4, 7),
-                     conv_set, dt, fixed_point_position)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallConvolutionLayerDataset(),
+                                                                                                                      framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                              framework::dataset::make("DataType", DataType::F32)))
 {
-    // Compute function
-    Tensor dst = compute_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_qs8);
+    validate(Accessor(_target), _reference, tolerance_f32);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(LargeConvolutionLayer,
-                     AlexNetConvolutionLayerDataset() * boost::unit_test::data::make(DataType::QS8) * boost::unit_test::data::xrange(4, 7),
-                     conv_set, dt, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                    framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                            framework::dataset::make("DataType", DataType::F32)))
 {
-    // Compute function
-    Tensor dst = compute_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_convolution_layer(conv_set.src_shape, conv_set.weights_shape, conv_set.bias_shape, conv_set.dst_shape, dt, conv_set.info, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_qs8);
+    validate(Accessor(_target), _reference, tolerance_f32);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
\ No newline at end of file
+template <typename T>
+using NEConvolutionLayerFixedPointFixture = ConvolutionValidationFixedPointFixture<Tensor, Accessor, NEConvolutionLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// We test for fixed point precision [4,6]
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallConvolutionLayerDataset(),
+                       framework::dataset::make("ReshapeWeights", { true, false })),
+                       framework::dataset::make("DataType", DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 4, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                       framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                                       framework::dataset::make("DataType", DataType::QS8)),
+                                                                                                                       framework::dataset::make("FractionalBits", 4, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallConvolutionLayerDataset(),
+                       framework::dataset::make("ReshapeWeights", { true, false })),
+                       framework::dataset::make("DataType", DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeConvolutionLayerDataset(),
+                                                                                                                        framework::dataset::make("ReshapeWeights", { true, false })),
+                                                                                                                        framework::dataset::make("DataType", DataType::QS16)),
+                                                                                                                        framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/ConvolutionLayerDirect.cpp b/tests/validation/NEON/ConvolutionLayerDirect.cpp
deleted file mode 100644
index 4e36e33..0000000
--- a/tests/validation/NEON/ConvolutionLayerDirect.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/functions/NEDirectConvolutionLayer.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-#include <tuple>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-const float tolerance_fp  = 1e-3f; /**< Tolerance for floating point tests */
-const float tolerance_qs8 = 1;     /**< Tolerance for fixed point tests */
-
-/** Compute NEON direct convolution layer function.
- *
- * @param[in] src_shape            Shape of the input tensor.
- * @param[in] weights_shape        Shape of the weights.
- * @param[in] bias_shape           Shape of the bias tensor.
- * @param[in] dst_shape            Shape of the output tensor.
- * @param[in] dt                   Data type of input, convolution matrix and output tensors.
- * @param[in] conv_info            Padding and stride information.
- * @param[in] fixed_point_position (Optional) Number of bits for the fractional part of the fixed point numbers
- *
- * @return Computed output tensor.
-*/
-Tensor compute_convolution_layer(const TensorShape &src_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &dst_shape,
-                                 DataType dt, PadStrideInfo conv_info, int fixed_point_position = 0)
-{
-    // Create tensors
-    Tensor src     = create_tensor(src_shape, dt, 1, fixed_point_position);
-    Tensor weights = create_tensor(weights_shape, dt, 1, fixed_point_position);
-    Tensor bias    = create_tensor(bias_shape, dt, 1, fixed_point_position);
-    Tensor dst     = create_tensor(dst_shape, dt, 1, fixed_point_position);
-
-    // Create and configure function
-    NEDirectConvolutionLayer conv_layer;
-    conv_layer.configure(&src, &weights, &bias, &dst, conv_info);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    weights.allocator()->allocate();
-    bias.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!weights.info()->is_resizable());
-    BOOST_TEST(!bias.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    if(dt == DataType::F32)
-    {
-        std::uniform_real_distribution<> distribution(-1.f, 1.f);
-        library->fill(NEAccessor(src), distribution, 0);
-        library->fill(NEAccessor(weights), distribution, 1);
-        library->fill(NEAccessor(bias), distribution, 2);
-    }
-    else
-    {
-        library->fill_tensor_uniform(NEAccessor(src), 0);
-        library->fill_tensor_uniform(NEAccessor(weights), 1);
-        library->fill_tensor_uniform(NEAccessor(bias), 2);
-    }
-
-    // Compute function
-    conv_layer.run();
-
-    return dst;
-}
-
-TensorShape get_output_shape(TensorShape in_shape, TensorShape kernel_shape, const PadStrideInfo &conv_info)
-{
-    TensorShape out_shape(in_shape);
-    const std::pair<unsigned int, unsigned int> scaled_dims = arm_compute::scaled_dimensions(in_shape.x(),
-                                                                                             in_shape.y(),
-                                                                                             kernel_shape.x(),
-                                                                                             conv_info.stride().first, conv_info.stride().second,
-                                                                                             conv_info.pad().first, conv_info.pad().second,
-                                                                                             conv_info.round());
-    out_shape.set(0, scaled_dims.first);
-    out_shape.set(1, scaled_dims.second);
-    out_shape.set(2, kernel_shape[3]);
-    return out_shape;
-}
-
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(ConvolutionLayer)
-BOOST_AUTO_TEST_SUITE(Direct)
-
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(W1x1,
-                     DirectConvolutionShapes() * CNNFloatDataTypes() * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::make({ 1, 4, 8, 16 }),
-                     input_shape, dt, sx, sy, num_kernels)
-{
-    const unsigned int  kernel_size = 1;
-    const PadStrideInfo conv_info(sx, sy, 0, 0, DimensionRoundingType::FLOOR);
-    const TensorShape   w_shape(kernel_size, kernel_size, input_shape.z(), static_cast<unsigned int>(num_kernels));
-    const TensorShape   b_shape(static_cast<unsigned int>(num_kernels));
-    const TensorShape   d_shape(get_output_shape(input_shape, w_shape, conv_info));
-
-    Tensor dst = compute_convolution_layer(input_shape, w_shape, b_shape, d_shape, dt, conv_info);
-
-    RawTensor ref = Reference::compute_reference_convolution_layer(input_shape, w_shape, b_shape, d_shape, dt, conv_info, 0);
-
-    // Validate output
-    validate(NEAccessor(dst), ref);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(W3x3, DirectConvolutionShapes() * CNNFloatDataTypes() * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::xrange(0, 2,
-                     1)
-                     * boost::unit_test::data::xrange(0, 2, 1) * boost::unit_test::data::make({ 1, 4, 8, 16 }),
-                     input_shape, dt, sx, sy, px, py, num_kernels)
-{
-    const unsigned int  kernel_size = 3;
-    const PadStrideInfo conv_info(sx, sy, px, py, DimensionRoundingType::FLOOR);
-    const TensorShape   w_shape(kernel_size, kernel_size, input_shape.z(), static_cast<unsigned int>(num_kernels));
-    const TensorShape   b_shape(static_cast<unsigned int>(num_kernels));
-    const TensorShape   d_shape(get_output_shape(input_shape, w_shape, conv_info));
-
-    Tensor dst = compute_convolution_layer(input_shape, w_shape, b_shape, d_shape, dt, conv_info);
-
-    RawTensor ref = Reference::compute_reference_convolution_layer(input_shape, w_shape, b_shape, d_shape, dt, conv_info, 0);
-
-    // Validate output
-    validate(NEAccessor(dst), ref, tolerance_fp);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(W1x1,
-                     DirectConvolutionShapes() * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::make({ 1, 4, 8, 16 }) * boost::unit_test::data::make({ 4, 5 }),
-                     input_shape, sx, sy, num_kernels, fixed_point_position)
-{
-    const unsigned int  kernel_size = 1;
-    const PadStrideInfo conv_info(sx, sy, 0, 0, DimensionRoundingType::FLOOR);
-    const TensorShape   w_shape(kernel_size, kernel_size, input_shape.z(), static_cast<unsigned int>(num_kernels));
-    const TensorShape   b_shape(static_cast<unsigned int>(num_kernels));
-    const TensorShape   d_shape(get_output_shape(input_shape, w_shape, conv_info));
-
-    Tensor dst = compute_convolution_layer(input_shape, w_shape, b_shape, d_shape, DataType::QS8, conv_info, fixed_point_position);
-
-    RawTensor ref = Reference::compute_reference_convolution_layer(input_shape, w_shape, b_shape, d_shape, DataType::QS8, conv_info, fixed_point_position);
-
-    // Validate output
-    validate(NEAccessor(dst), ref);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(W3x3, DirectConvolutionShapes() * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::xrange(1, 3, 1) * boost::unit_test::data::xrange(0, 2, 1)
-                     * boost::unit_test::data::xrange(0, 2, 1) * boost::unit_test::data::make({ 1, 4, 8, 16 }) * boost::unit_test::data::make({ 4, 5 }),
-                     input_shape, sx, sy, px, py, num_kernels, fixed_point_position)
-{
-    const unsigned int  kernel_size = 3;
-    const PadStrideInfo conv_info(sx, sy, px, py, DimensionRoundingType::FLOOR);
-    const TensorShape   w_shape(kernel_size, kernel_size, input_shape.z(), static_cast<unsigned int>(num_kernels));
-    const TensorShape   b_shape(static_cast<unsigned int>(num_kernels));
-    const TensorShape   d_shape(get_output_shape(input_shape, w_shape, conv_info));
-
-    Tensor dst = compute_convolution_layer(input_shape, w_shape, b_shape, d_shape, DataType::QS8, conv_info, fixed_point_position);
-
-    RawTensor ref = Reference::compute_reference_convolution_layer(input_shape, w_shape, b_shape, d_shape, DataType::QS8, conv_info, fixed_point_position);
-
-    // Validate output
-    validate(NEAccessor(dst), ref, tolerance_qs8);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
\ No newline at end of file
diff --git a/tests/validation/NEON/DepthConcatenateLayer.cpp b/tests/validation/NEON/DepthConcatenateLayer.cpp
new file mode 100644
index 0000000..f7957a5
--- /dev/null
+++ b/tests/validation/NEON/DepthConcatenateLayer.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEDepthConcatenate.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DepthConcatenateLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(DepthConcatenateLayer)
+
+template <typename T>
+using NEDepthConcatenateLayerFixture = DepthConcatenateValidationFixture<Tensor, ITensor, Accessor, NEDepthConcatenate, T>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConcatenateLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                                  DataType::F16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConcatenateLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::DepthConcatenateShapes(), framework::dataset::make("DataType",
+                                                                                                                DataType::F16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConcatenateLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConcatenateLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::DepthConcatenateShapes(), framework::dataset::make("DataType",
+                                                                                                                 DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConcatenateLayerFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(),
+                                                                                                                    framework::dataset::make("DataType",
+                                                                                                                            DataType::QS8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConcatenateLayerFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::DepthConcatenateShapes(),
+                                                                                                                  framework::dataset::make("DataType",
+                                                                                                                          DataType::QS8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConcatenateLayerFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(),
+                                                                                                                     framework::dataset::make("DataType",
+                                                                                                                             DataType::QS16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConcatenateLayerFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(datasets::DepthConcatenateShapes(),
+                                                                                                                   framework::dataset::make("DataType",
+                                                                                                                           DataType::QS16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/DepthConvert.cpp b/tests/validation/NEON/DepthConvert.cpp
index ec0bb7c..e036cc4 100644
--- a/tests/validation/NEON/DepthConvert.cpp
+++ b/tests/validation/NEON/DepthConvert.cpp
@@ -18,483 +18,467 @@
  * 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
+ * OUT OF OR IN CONCLCTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEDepthConvert.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ConvertPolicyDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DepthConvertFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-/** Compute Neon depth convert function.
- *
- * @param[in] shape                Shape of the input and output tensors.
- * @param[in] dt_in                Data type of input tensor.
- * @param[in] dt_out               Data type of the output tensor.
- * @param[in] policy               Conversion policy.
- * @param[in] shift                Value for down/up conversions. Must be 0 <= shift < 8.
- * @param[in] fixed_point_position Fixed point position.
- *
- * @return Computed output tensor.
- */
-Tensor compute_depth_convert(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift, uint32_t fixed_point_position)
+/** Input data sets **/
+const auto DepthConvertU8toU16Dataset             = combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::U16));
+const auto DepthConvertU8toS16Dataset             = combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::S16));
+const auto DepthConvertU8toS32Dataset             = combine(framework::dataset::make("DataType", DataType::U8), framework::dataset::make("DataType", DataType::S32));
+const auto DepthConvertU16toU8Dataset             = combine(framework::dataset::make("DataType", DataType::U16), framework::dataset::make("DataType", DataType::U8));
+const auto DepthConvertU16toU32Dataset            = combine(framework::dataset::make("DataType", DataType::U16), framework::dataset::make("DataType", DataType::U32));
+const auto DepthConvertS16toU8Dataset             = combine(framework::dataset::make("DataType", DataType::S16), framework::dataset::make("DataType", DataType::U8));
+const auto DepthConvertS16toS32Dataset            = combine(framework::dataset::make("DataType", DataType::S16), framework::dataset::make("DataType", DataType::S32));
+const auto DepthConvertQS8toFP32Dataset           = combine(framework::dataset::make("DataType", DataType::QS8), framework::dataset::make("DataType", DataType::F32));
+const auto DepthConvertQS16toFP32Dataset          = combine(framework::dataset::make("DataType", DataType::QS16), framework::dataset::make("DataType", DataType::F32));
+const auto DepthConvertFP32toQS8Dataset           = combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::QS8));
+const auto DepthConvertFP32toQS16Dataset          = combine(framework::dataset::make("DataType", DataType::F32), framework::dataset::make("DataType", DataType::QS16));
+const auto DepthConvertShiftDataset               = framework::dataset::make("Shift", 0, 7);
+const auto DepthConvertFixedPointQuantizedDataset = framework::dataset::make("FractionalBits", 1, 7);
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(DepthConvert)
+template <typename T>
+using NEDepthConvertToU16Fixture = DepthConvertValidationFixture<Tensor, Accessor, NEDepthConvert, T, uint16_t>;
+template <typename T>
+using NEDepthConvertToS16Fixture = DepthConvertValidationFixture<Tensor, Accessor, NEDepthConvert, T, int16_t>;
+template <typename T>
+using NEDepthConvertToS32Fixture = DepthConvertValidationFixture<Tensor, Accessor, NEDepthConvert, T, int32_t>;
+template <typename T>
+using NEDepthConvertToU8Fixture = DepthConvertValidationFixture<Tensor, Accessor, NEDepthConvert, T, uint8_t>;
+template <typename T>
+using NEDepthConvertToU32Fixture = DepthConvertValidationFixture<Tensor, Accessor, NEDepthConvert, T, uint32_t>;
+template <typename T>
+using NEDepthConvertToFP32FixedPointFixture = DepthConvertValidationFractionalBitsFixture<Tensor, Accessor, NEDepthConvert, T, float>;
+template <typename T>
+using NEDepthConvertToQS8FixedPointFixture = DepthConvertValidationFractionalBitsFixture<Tensor, Accessor, NEDepthConvert, T, int8_t>;
+template <typename T>
+using NEDepthConvertToQS16FixedPointFixture = DepthConvertValidationFractionalBitsFixture<Tensor, Accessor, NEDepthConvert, T, int16_t>;
+
+TEST_SUITE(U8_to_U16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
+    int fixed_point_position = 0;
+
     // Create tensors
-    Tensor src = create_tensor(shape, dt_in, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, dt_out, 1, fixed_point_position);
+    Tensor src = create_tensor<Tensor>(shape, DataType::U8, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::U16, 1, fixed_point_position);
 
-    // Create and configure function
-    NEDepthConvert depth_convert;
-    depth_convert.configure(&src, &dst, policy, shift);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src), 0);
-
-    // Compute function
-    depth_convert.run();
-
-    return dst;
-}
-/** Configure and validate region/padding function.
- *
- * @param[in] shape                Shape of the input and output tensors.
- * @param[in] dt_in                Data type of input tensor.
- * @param[in] dt_out               Data type of the output tensor.
- * @param[in] policy               Conversion policy.
- * @param[in] shift                Value for down/up conversions. Must be 0 <= shift < 8.
- * @param[in] fixed_point_position Fixed point position.
- *
- */
-
-void compute_configure_validate(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift, uint32_t fixed_point_position)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, dt_in, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, dt_out, 1, fixed_point_position);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
+    // Create and Configure function
     NEDepthConvert depth_convert;
     depth_convert.configure(&src, &dst, policy, shift);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src.info()->valid_region(), valid_region);
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
     validate(src.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
-} // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(DepthConvert)
-
-BOOST_AUTO_TEST_SUITE(QS8_to_F32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE })
-                     * boost::unit_test::data::xrange(1, 7, 1),
-                     shape, policy, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConvertToU16Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU8toU16Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::QS8, DataType::F32, policy, 0, fixed_point_position);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE })
-                     * boost::unit_test::data::xrange(1, 7, 1),
-                     shape, policy, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::QS8, DataType::F32, policy, 0, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::QS8, DataType::F32, policy, 0, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE })
-                     * boost::unit_test::data::xrange(1, 7, 1),
-                     shape, policy, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConvertToU16Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU8toU16Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::QS8, DataType::F32, policy, 0, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::QS8, DataType::F32, policy, 0, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(U8_to_S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
+{
+    int fixed_point_position = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::U8, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::S16, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(F32_to_QS8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE })
-                     * boost::unit_test::data::xrange(1, 7, 1),
-                     shape, policy, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConvertToS16Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU8toS16Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::F32, DataType::QS8, policy, 0, fixed_point_position);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE })
-                     * boost::unit_test::data::xrange(1, 7, 1),
-                     shape, policy, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::F32, DataType::QS8, policy, 0, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::F32, DataType::QS8, policy, 0, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE })
-                     * boost::unit_test::data::xrange(1, 7, 1),
-                     shape, policy, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConvertToS16Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU8toS16Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::F32, DataType::QS8, policy, 0, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::F32, DataType::QS8, policy, 0, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(U8_to_U16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE_END()
+TEST_SUITE(U8_to_S32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U8, DataType::U16, policy, shift, 0);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::U8, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::S32, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConvertToS32Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU8toS32Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U8, DataType::U16, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::U16, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConvertToS32Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU8toS32Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U8, DataType::U16, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::U16, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U8_to_S16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(U16_to_U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U8, DataType::S16, policy, shift, 0);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::U16, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::U8, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConvertToU8Fixture<uint16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU16toU8Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U8, DataType::S16, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S16, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConvertToU8Fixture<uint16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU16toU8Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U8, DataType::S16, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S16, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U8_to_S32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(U16_to_U32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U8, DataType::S32, policy, shift, 0);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::U16, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::U32, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConvertToU32Fixture<uint16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertU16toU32Dataset),
+                                                                                                                  framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                  DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U8, DataType::S32, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConvertToU32Fixture<uint16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertU16toU32Dataset),
+                                                                                                                        framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U8, DataType::S32, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U8, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U16_to_U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(S16_to_U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U16, DataType::U8, policy, shift, 0);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::S16, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::U8, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConvertToU8Fixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertS16toU8Dataset),
+                                                                                                                        framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U16, DataType::U8, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConvertToU8Fixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertS16toU8Dataset),
+                                                                                                                      framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                              DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U16, DataType::U8, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(U16_to_U32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(S16_to_S32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertShiftDataset),
+               shape, policy, shift)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::U16, DataType::U32, policy, shift, 0);
+    int fixed_point_position = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::S16, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::S32, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDepthConvertToS32Fixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertS16toS32Dataset),
+                                                                                                                 framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                                 DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U16, DataType::U32, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U32, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDepthConvertToS32Fixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertS16toS32Dataset),
+                                                                                                                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                                                               DepthConvertShiftDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::U16, DataType::U32, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::U16, DataType::U32, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE(S16_to_U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+TEST_SUITE(Quantized_to_FP32)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::QS8, DataType::QS16 })),
+                                                                           framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertFixedPointQuantizedDataset),
+               shape, dt, policy, fixed_point_position)
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::S16, DataType::U8, policy, shift, 0);
+    int shift = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, dt, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::F32, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmallQS8, NEDepthConvertToFP32FixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertQS8toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::S16, DataType::U8, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunSmallQS16, NEDepthConvertToFP32FixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertQS16toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::S16, DataType::U8, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::U8, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(S16_to_S32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLargeQS8, NEDepthConvertToFP32FixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertQS8toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
 {
-    // Compute configure and validate region/padding
-    compute_configure_validate(shape, DataType::S16, DataType::S32, policy, shift, 0);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
-{
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::S16, DataType::S32, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     shape, policy, shift)
+FIXTURE_DATA_TEST_CASE(RunLargeQS16, NEDepthConvertToFP32FixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertQS16toFP32Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
 {
-    // Compute function
-    Tensor dst = compute_depth_convert(shape, DataType::S16, DataType::S32, policy, shift, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::S16, DataType::S32, policy, shift, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE(FP32_to_Quantized)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::QS8, DataType::QS16 })),
+                                                                           framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                                                                   DepthConvertFixedPointQuantizedDataset),
+               shape, dt, policy, fixed_point_position)
+{
+    int shift = 0;
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::F32, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, dt, 1, fixed_point_position);
+
+    // Create and Configure function
+    NEDepthConvert depth_convert;
+    depth_convert.configure(&src, &dst, policy, shift);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallQS8, NEDepthConvertToQS8FixedPointFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertFP32toQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallQS16, NEDepthConvertToQS16FixedPointFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), DepthConvertFP32toQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeQS8, NEDepthConvertToQS8FixedPointFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertFP32toQS8Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeQS16, NEDepthConvertToQS16FixedPointFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), DepthConvertFP32toQS16Dataset),
+                       framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE, ConvertPolicy::WRAP })),
+                       DepthConvertFixedPointQuantizedDataset))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/DequantizationLayer.cpp b/tests/validation/NEON/DequantizationLayer.cpp
new file mode 100644
index 0000000..9bdba72
--- /dev/null
+++ b/tests/validation/NEON/DequantizationLayer.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEDequantizationLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DequantizationLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+constexpr AbsoluteTolerance<float> tolerance_f32(0.001f);
+
+const auto DequantizationShapes = concat(concat(concat(datasets::Small3DShapes(),
+                                                       datasets::Large3DShapes()),
+                                                datasets::Small4DShapes()),
+                                         datasets::Large4DShapes());
+
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(DequantizationLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(DequantizationShapes, framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    TensorShape shape_min_max = shape;
+    shape_min_max.set(Window::DimX, 2);
+
+    // Remove Y and Z dimensions and keep the batches
+    shape_min_max.remove_dimension(1);
+    shape_min_max.remove_dimension(1);
+
+    // Create tensors
+    Tensor src     = create_tensor<Tensor>(shape, data_type);
+    Tensor dst     = create_tensor<Tensor>(shape, DataType::F32);
+    Tensor min_max = create_tensor<Tensor>(shape_min_max, DataType::F32);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(min_max.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    NEDequantizationLayer dequant_layer;
+    dequant_layer.configure(&src, &dst, &min_max);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate valid region of min_max tensor
+    const ValidRegion valid_region_min_max = shape_to_valid_region(shape_min_max);
+    validate(min_max.info()->valid_region(), valid_region_min_max);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 8).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+
+    // Validate padding of min_max tensor
+    const PaddingSize padding_min_max = PaddingCalculator(shape_min_max.x(), 2).required_padding();
+    validate(min_max.info()->padding(), padding_min_max);
+}
+
+template <typename T>
+using NEDequantizationLayerFixture = DequantizationValidationFixture<Tensor, Accessor, NEDequantizationLayer, T>;
+
+TEST_SUITE(Integer)
+TEST_SUITE(U8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEDequantizationLayerFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                                   framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEDequantizationLayerFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                                 framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/DirectConvolutionLayer.cpp b/tests/validation/NEON/DirectConvolutionLayer.cpp
new file mode 100644
index 0000000..314041b
--- /dev/null
+++ b/tests/validation/NEON/DirectConvolutionLayer.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEDirectConvolutionLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/DirectConvolutionLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr AbsoluteTolerance<float> tolerance_qs(1.f); /**< Tolerance for fixed point tests */
+#ifdef ARM_COMPUTE_ENABLE_FP16
+constexpr AbsoluteTolerance<float> tolerance_fp16(0.01f);  /**< Tolerance for half precision floating point tests */
+#endif                                                     /* ARM_COMPUTE_ENABLE_FP16 */
+constexpr AbsoluteTolerance<float> tolerance_fp32(0.001f); /**< Tolerance for floating point tests */
+
+/** Direct convolution data set. */
+const auto data_pad_f32 = concat(concat(combine(framework::dataset::make("PadX", 0),
+                                                combine(framework::dataset::make("PadY", 0),
+                                                        framework::dataset::make("KernelSize", 1))),
+                                        combine(framework::dataset::make("PadX", 0, 2),
+                                                combine(framework::dataset::make("PadY", 0, 2),
+                                                        framework::dataset::make("KernelSize", 3)))),
+                                 combine(framework::dataset::make("PadX", 0, 3),
+                                         combine(framework::dataset::make("PadY", 0, 3),
+                                                 framework::dataset::make("KernelSize", 5))));
+
+const auto data_pad_qs8 = concat(combine(framework::dataset::make("PadX", 0),
+                                         combine(framework::dataset::make("PadY", 0),
+                                                 framework::dataset::make("KernelSize", 1))),
+                                 combine(framework::dataset::make("PadX", 0, 2),
+                                         combine(framework::dataset::make("PadY", 0, 2),
+                                                 framework::dataset::make("KernelSize", 3))));
+
+const auto data_f32 = combine(datasets::SmallDirectConvolutionShapes(),
+                              combine(framework::dataset::make("StrideX", 1, 3),
+                                      combine(framework::dataset::make("StrideY", 1, 3),
+                                              combine(data_pad_f32,
+                                                      framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
+
+const auto data_qs8 = combine(datasets::SmallDirectConvolutionShapes(),
+                              combine(framework::dataset::make("StrideX", 1, 3),
+                                      combine(framework::dataset::make("StrideY", 1, 3),
+                                              combine(data_pad_qs8,
+                                                      framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))));
+
+/** Direct convolution QS16 data set. */
+const auto data_qs16 = combine(datasets::SmallDirectConvolutionShapes(),
+                               combine(framework::dataset::make("StrideX", 1, 3),
+                                       combine(framework::dataset::make("StrideY", 1, 3),
+                                               combine(framework::dataset::make("PadX", 0),
+                                                       combine(framework::dataset::make("PadY", 0),
+                                                               combine(framework::dataset::make("KernelSize", 1),
+                                                                       framework::dataset::make("NumKernels", { 1, 4, 8, 16 })))))));
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(DirectConvolutionLayer)
+
+template <typename T>
+using NEDirectConvolutionLayerFixture = DirectConvolutionValidationFixture<Tensor, Accessor, NEDirectConvolutionLayer, T>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(Run, NEDirectConvolutionLayerFixture<half>, framework::DatasetMode::ALL, combine(data_f32, framework::dataset::make("DataType", DataType::F16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fp16);
+}
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(Run, NEDirectConvolutionLayerFixture<float>, framework::DatasetMode::ALL, combine(data_f32, framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fp32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using NEDirectConvolutionLayerFixedPointFixture = DirectConvolutionValidationFixedPointFixture<Tensor, Accessor, NEDirectConvolutionLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// We test for fixed point precision [4,6]
+FIXTURE_DATA_TEST_CASE(Run, NEDirectConvolutionLayerFixedPointFixture<int8_t>, framework::DatasetMode::ALL, combine(combine(data_qs8, framework::dataset::make("DataType", DataType::QS8)),
+                                                                                                                    framework::dataset::make("FractionalBits", 4, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// We test for fixed point precision [4,13]
+FIXTURE_DATA_TEST_CASE(Run, NEDirectConvolutionLayerFixedPointFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(data_qs16, framework::dataset::make("DataType", DataType::QS16)),
+                                                                                                                     framework::dataset::make("FractionalBits", 4, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/FillBorder.cpp b/tests/validation/NEON/FillBorder.cpp
deleted file mode 100644
index 9fbeb99..0000000
--- a/tests/validation/NEON/FillBorder.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/NEON/kernels/NEFillBorderKernel.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(FillBorder, BorderModes() * boost::unit_test::data::make({ PaddingSize{ 0 }, PaddingSize{ 1, 0, 1, 2 }, PaddingSize{ 10 } }), border_mode, padding)
-{
-    constexpr uint8_t border_value = 42U;
-    constexpr uint8_t tensor_value = 89U;
-    BorderSize        border_size{ 5 };
-
-    // Create tensors
-    Tensor src = create_tensor(TensorShape{ 10U, 10U, 2U }, DataType::U8);
-
-    src.info()->extend_padding(padding);
-
-    // Allocate tensor
-    src.allocator()->allocate();
-
-    // Check padding is as required
-    validate(src.info()->padding(), padding);
-
-    // Fill tensor with constant value
-    std::uniform_int_distribution<uint8_t> distribution{ tensor_value, tensor_value };
-    library->fill(NEAccessor(src), distribution, 0);
-
-    // Create and configure kernel
-    NEFillBorderKernel fill_border;
-    fill_border.configure(&src, border_size, border_mode, border_value);
-
-    // Run kernel
-    fill_border.run(fill_border.window());
-
-    // Validate border
-    border_size.limit(padding);
-    validate(NEAccessor(src), border_size, border_mode, &border_value);
-
-    // Validate tensor
-    validate(NEAccessor(src), &tensor_value);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/Fixedpoint/Exp_QS8.cpp b/tests/validation/NEON/Fixedpoint/Exp_QS8.cpp
deleted file mode 100644
index 086314f..0000000
--- a/tests/validation/NEON/Fixedpoint/Exp_QS8.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/ReferenceCPP.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/NEON/NEFixedPoint.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-const float tolerance = 0.0f; /**< Tolerance value for comparing reference's output against implementation's output */
-
-/** Compute Neon exponential function for signed 8bit fixed point.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_exp_qs8(const TensorShape &shape, int fixed_point_position)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-
-    constexpr unsigned int num_elems_processed_per_iteration = 16;
-    Window                 window                            = calculate_max_window(*src.info(), Steps(num_elems_processed_per_iteration));
-    AccessWindowHorizontal input_access(src.info(), 0, num_elems_processed_per_iteration);
-    AccessWindowHorizontal output_access(dst.info(), 0, num_elems_processed_per_iteration);
-
-    update_window_and_padding(window, input_access, output_access);
-    output_access.set_valid_region(window, src.info()->valid_region());
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors. Keep the range between (1, (1 << (fixed_point_position - 1))) so the result won't
-    // overflow. E.g. e^7 = 1096, which cannot be represented in QS8
-    std::uniform_int_distribution<> distribution(1, (1 << (fixed_point_position - 1)));
-    library->fill(NEAccessor(src), distribution, 0);
-
-    Iterator input(&src, window);
-    Iterator output(&dst, window);
-
-    execute_window_loop(window, [&](const Coordinates & id)
-    {
-        qint8x16_t in = vld1q_s8(reinterpret_cast<const qint8_t *>(input.ptr()));
-        // Use saturated exp
-        vst1q_s8(reinterpret_cast<qint8_t *>(output.ptr()), vqexpq_qs8(in, fixed_point_position));
-    },
-    input, output);
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(FixedPoint)
-BOOST_AUTO_TEST_SUITE(QS8)
-BOOST_AUTO_TEST_SUITE(Exp)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunSmall, Small1DShape() * boost::unit_test::data::xrange(1, 7), shape, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_exp_qs8(shape, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fixed_point_operation(shape, DataType::QS8, DataType::QS8, FixedPointOp::EXP, fixed_point_position);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance, 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/Fixedpoint/Invsqrt_QS8.cpp b/tests/validation/NEON/Fixedpoint/Invsqrt_QS8.cpp
deleted file mode 100644
index 3308f7d..0000000
--- a/tests/validation/NEON/Fixedpoint/Invsqrt_QS8.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/ReferenceCPP.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/NEON/NEFixedPoint.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-const float tolerance = 3; /**< Tolerance value for comparing reference's output against implementation's output */
-
-/** Compute Neon inverse square root function for signed 8bit fixed point.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_invsqrt_qs8(const TensorShape &shape, int fixed_point_position)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-
-    constexpr unsigned int num_elems_processed_per_iteration = 16;
-    Window                 window                            = calculate_max_window(*src.info(), Steps(num_elems_processed_per_iteration));
-    AccessWindowHorizontal input_access(src.info(), 0, num_elems_processed_per_iteration);
-    AccessWindowHorizontal output_access(dst.info(), 0, num_elems_processed_per_iteration);
-
-    update_window_and_padding(window, input_access, output_access);
-    output_access.set_valid_region(window, src.info()->valid_region());
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors. Keep the range between (32, 127) so the result won't
-    // overflow. E.g. for Q2.5 invsqrt(0.001) = 31.6, which cannot be represented.
-    std::uniform_int_distribution<> distribution(32, 127);
-    library->fill(NEAccessor(src), distribution, 0);
-
-    Iterator input(&src, window);
-    Iterator output(&dst, window);
-
-    execute_window_loop(window, [&](const Coordinates & id)
-    {
-        qint8x16_t in = vld1q_s8(reinterpret_cast<const qint8_t *>(input.ptr()));
-        vst1q_s8(reinterpret_cast<qint8_t *>(output.ptr()), vinvsqrtq_qs8(in, fixed_point_position));
-    },
-    input, output);
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(FixedPoint)
-BOOST_AUTO_TEST_SUITE(QS8)
-BOOST_AUTO_TEST_SUITE(Invsqrt)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Small1DShape, SmallShapes() * boost::unit_test::data::xrange(1, 6), shape, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_invsqrt_qs8(shape, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fixed_point_operation(shape, DataType::QS8, DataType::QS8, FixedPointOp::INV_SQRT, fixed_point_position);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance, 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/Fixedpoint/Log_QS8.cpp b/tests/validation/NEON/Fixedpoint/Log_QS8.cpp
deleted file mode 100644
index 7b734c1..0000000
--- a/tests/validation/NEON/Fixedpoint/Log_QS8.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/ReferenceCPP.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/NEON/NEFixedPoint.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-const float tolerance = 5; /**< Tolerance value for comparing reference's output against implementation's output */
-
-/** Compute Neon logarithm function for signed 8bit fixed point.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_log_qs8(const TensorShape &shape, int fixed_point_position)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-
-    constexpr unsigned int num_elems_processed_per_iteration = 16;
-    Window                 window                            = calculate_max_window(*src.info(), Steps(num_elems_processed_per_iteration));
-    AccessWindowHorizontal input_access(src.info(), 0, num_elems_processed_per_iteration);
-    AccessWindowHorizontal output_access(dst.info(), 0, num_elems_processed_per_iteration);
-
-    update_window_and_padding(window, input_access, output_access);
-    output_access.set_valid_region(window, src.info()->valid_region());
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors. Keep the range between ((1 << (fixed_point_position - 1), 63) so the result won't
-    // overflow. E.g. for Q2.5 ln(0.001) = -6.9, which cannot be represented.
-    std::uniform_int_distribution<> distribution((1 << (fixed_point_position - 1)), 63);
-    library->fill(NEAccessor(src), distribution, 0);
-
-    Iterator input(&src, window);
-    Iterator output(&dst, window);
-
-    execute_window_loop(window, [&](const Coordinates & id)
-    {
-        qint8x16_t in = vld1q_s8(reinterpret_cast<const qint8_t *>(input.ptr()));
-        vst1q_s8(reinterpret_cast<qint8_t *>(output.ptr()), vlogq_qs8(in, fixed_point_position));
-    },
-    input, output);
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(FixedPoint)
-BOOST_AUTO_TEST_SUITE(QS8)
-BOOST_AUTO_TEST_SUITE(Log)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunSmall, Small1DShape() * boost::unit_test::data::xrange(3, 6), shape, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_log_qs8(shape, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fixed_point_operation(shape, DataType::QS8, DataType::QS8, FixedPointOp::LOG, fixed_point_position);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance, 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/Fixedpoint/Reciprocal_QS8.cpp b/tests/validation/NEON/Fixedpoint/Reciprocal_QS8.cpp
deleted file mode 100644
index 4c1c782..0000000
--- a/tests/validation/NEON/Fixedpoint/Reciprocal_QS8.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/ReferenceCPP.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/NEON/NEFixedPoint.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-const float tolerance = 3; /**< Tolerance value for comparing reference's output against implementation's output */
-
-/** Compute Neon reciprocal function for signed 8bit fixed point.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_reciprocal_qs8(const TensorShape &shape, int fixed_point_position)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, DataType::QS8, 1, fixed_point_position);
-
-    constexpr unsigned int num_elems_processed_per_iteration = 16;
-    Window                 window                            = calculate_max_window(*src.info(), Steps(num_elems_processed_per_iteration));
-    AccessWindowHorizontal input_access(src.info(), 0, num_elems_processed_per_iteration);
-    AccessWindowHorizontal output_access(dst.info(), 0, num_elems_processed_per_iteration);
-
-    update_window_and_padding(window, input_access, output_access);
-    output_access.set_valid_region(window, src.info()->valid_region());
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors. Keep the range between (15, 100) so the result won't
-    // overflow. E.g. for Q2.5 reciprocal(0.001) = 1000, which cannot be represented.
-    std::uniform_int_distribution<> distribution(15, 100);
-    library->fill(NEAccessor(src), distribution, 0);
-
-    Iterator input(&src, window);
-    Iterator output(&dst, window);
-
-    execute_window_loop(window, [&](const Coordinates & id)
-    {
-        qint8x16_t in = vld1q_s8(reinterpret_cast<const qint8_t *>(input.ptr()));
-        vst1q_s8(reinterpret_cast<qint8_t *>(output.ptr()), vrecipq_qs8(in, fixed_point_position));
-    },
-    input, output);
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(FixedPoint)
-BOOST_AUTO_TEST_SUITE(QS8)
-BOOST_AUTO_TEST_SUITE(Reciprocal)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunSmall, Small1DShape() * boost::unit_test::data::xrange(1, 6), shape, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_reciprocal_qs8(shape, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fixed_point_operation(shape, DataType::QS8, DataType::QS8, FixedPointOp::RECIPROCAL, fixed_point_position);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance, 0);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/Floor.cpp b/tests/validation/NEON/Floor.cpp
new file mode 100644
index 0000000..c14b859
--- /dev/null
+++ b/tests/validation/NEON/Floor.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEFloor.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/FloorFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(Floor)
+
+template <typename T>
+using NEFloorFixture = FloorValidationFixture<Tensor, Accessor, NEFloor, T>;
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEFloorFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEFloorFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/FullyConnectedLayer.cpp b/tests/validation/NEON/FullyConnectedLayer.cpp
index bda235b..b5ae48a 100644
--- a/tests/validation/NEON/FullyConnectedLayer.cpp
+++ b/tests/validation/NEON/FullyConnectedLayer.cpp
@@ -21,201 +21,190 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TypePrinter.h"
-#include "dataset/FullyConnectedLayerDataset.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Error.h"
-#include "arm_compute/core/Helpers.h"
+#include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/FullyConnectedLayerDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/FullyConnectedLayerFixture.h"
 
-#include <random>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-const float tolerance_f32 = 1e-03f; /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
-const float tolerance_qs8 = 1.0f;   /**< Tolerance value for comparing reference's output against implementation's output for DataType::QS8 */
+/** Tolerance for float operations */
+constexpr RelativeTolerance<float> tolerance_f32(0.01f);
+#ifdef ARM_COMPUTE_ENABLE_FP16
+constexpr RelativeTolerance<float> tolerance_f16(0.01f);
+#endif /* ARM_COMPUTE_ENABLE_FP16*/
+/** Tolerance for fixed point operations */
+constexpr AbsoluteTolerance<float> tolerance_fixed_point(1.f);
 
-Tensor compute_fully_connected_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, DataType dt,
-                                     bool transpose_weights, int fixed_point_position)
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
 {
-    // Create tensors
-    Tensor src  = create_tensor(input_shape, dt, 1, fixed_point_position);
-    Tensor bias = create_tensor(bias_shape, dt, 1, fixed_point_position);
-    Tensor dst  = create_tensor(output_shape, dt, 1, fixed_point_position);
+#ifdef ARM_COMPUTE_ENABLE_FP16
+    DataType::F16,
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
 
-    // Swap the first and second dimension of weights' shape if transpose_weights is true
-    TensorShape ws = weights_shape;
-    if(transpose_weights)
-    {
-        const size_t dimx = ws.x();
-        ws.set(0, ws.y());
-        ws.set(1, dimx);
-    }
-
-    Tensor weights = create_tensor(ws, dt, 1, fixed_point_position);
-
-    // Create and configure function.
-    // Note: We pass the weights already transposed
-    NEFullyConnectedLayer fc;
-    fc.configure(&src, &weights, &bias, &dst, false);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    weights.allocator()->allocate();
-    bias.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!weights.info()->is_resizable());
-    BOOST_TEST(!bias.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    if(dt == DataType::F32)
-    {
-        std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
-        library->fill(NEAccessor(src), distribution, 0);
-        library->fill(NEAccessor(weights), distribution, 1);
-        library->fill(NEAccessor(bias), distribution, 2);
-    }
-    else
-    {
-        library->fill_tensor_uniform(NEAccessor(src), 0);
-        library->fill_tensor_uniform(NEAccessor(weights), 1);
-        library->fill_tensor_uniform(NEAccessor(bias), 2);
-    }
-
-    // Compute NEFullyConnectedLayer function
-    fc.run();
-
-    return dst;
-}
+const auto FullyConnectedParameters = combine(framework::dataset::make("TransposeWeights", { false, true }), framework::dataset::make("ReshapeWeights", { false, true }));
 } // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(FullyConnectedLayer)
+TEST_SUITE(NEON)
+TEST_SUITE(FullyConnectedLayer)
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration,
-                     SmallFullyConnectedLayerDataset() * boost::unit_test::data::make({ DataType::F32, DataType::QS8 }),
-                     fc_set, dt)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(framework::dataset::concat(datasets::SmallFullyConnectedLayerDataset(), datasets::LargeFullyConnectedLayerDataset()),
+                                                                           FullyConnectedParameters),
+                                                                   CNNDataTypes),
+               src_shape, weights_shape, bias_shape, dst_shape, transpose_weights, reshape_weights, data_type)
 {
     // Set fixed point position data type allowed
-    int fixed_point_position = (dt == DataType::F32) ? 0 : 3;
+    int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
 
-    // Create tensors
-    Tensor src  = create_tensor(fc_set.src_shape, dt, 1, fixed_point_position);
-    Tensor bias = create_tensor(fc_set.bias_shape, dt, 1, fixed_point_position);
-    Tensor dst  = create_tensor(fc_set.dst_shape, dt, 1, fixed_point_position);
+    TensorShape ws(weights_shape);
 
-    // Swap the first and second dimension of weights' shape if transpose_weights is true
-    TensorShape ws = fc_set.weights_shape;
-    if(fc_set.transpose_weights)
+    // Transpose weights if not done in the function
+    if(!reshape_weights || !transpose_weights)
     {
-        const size_t dimx = ws.x();
+        const size_t shape_x = ws.x();
         ws.set(0, ws.y());
-        ws.set(1, dimx);
+        ws.set(1, shape_x);
+
+        // Weights have to be passed reshaped
+        // Transpose 1xW for batched version
+        if(!reshape_weights && dst_shape.y() > 1)
+        {
+            const float  transpose_width = 16.0f / data_size_from_type(data_type);
+            const size_t shape_x         = ws.x();
+            ws.set(0, ws.y() * static_cast<unsigned int>(transpose_width));
+            ws.set(1, static_cast<unsigned int>(std::ceil(shape_x / transpose_width)));
+        }
     }
 
-    Tensor weights = create_tensor(ws, dt, 1, fixed_point_position);
+    // Create tensors
+    Tensor src     = create_tensor<Tensor>(src_shape, data_type, 1, fixed_point_position);
+    Tensor weights = create_tensor<Tensor>(ws, data_type, 1, fixed_point_position);
+    Tensor bias    = create_tensor<Tensor>(bias_shape, data_type, 1, fixed_point_position);
+    Tensor dst     = create_tensor<Tensor>(dst_shape, data_type, 1, fixed_point_position);
 
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(weights.info()->is_resizable());
-    BOOST_TEST(bias.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function.
-    // Note: We pass the weights already transposed
     NEFullyConnectedLayer fc;
-    fc.configure(&src, &weights, &bias, &dst, false);
+    fc.configure(&src, &weights, &bias, &dst, transpose_weights, !reshape_weights);
 
     // Validate valid region
-    const ValidRegion src_valid_region     = shape_to_valid_region(fc_set.src_shape);
-    const ValidRegion weights_valid_region = shape_to_valid_region(ws);
-    const ValidRegion bias_valid_region    = shape_to_valid_region(fc_set.bias_shape);
-    const ValidRegion dst_valid_region     = shape_to_valid_region(fc_set.dst_shape);
-
-    validate(src.info()->valid_region(), src_valid_region);
-    validate(weights.info()->valid_region(), weights_valid_region);
-    validate(bias.info()->valid_region(), bias_valid_region);
+    const ValidRegion dst_valid_region = shape_to_valid_region(dst_shape);
     validate(dst.info()->valid_region(), dst_valid_region);
 }
 
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall,
-                     SmallFullyConnectedLayerDataset() * boost::unit_test::data::make({ DataType::F32 }),
-                     fc_set, dt)
+template <typename T>
+using NEFullyConnectedLayerFixture = FullyConnectedLayerValidationFixture<Tensor, Accessor, NEFullyConnectedLayer, T, true>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEFullyConnectedLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallFullyConnectedLayerDataset(),
+                                                                                                                        FullyConnectedParameters),
+                                                                                                                framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute function
-    Tensor dst = compute_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f32);
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge,
-                     LargeFullyConnectedLayerDataset() * boost::unit_test::data::make({ DataType::F32 }),
-                     fc_set, dt)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEFullyConnectedLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeFullyConnectedLayerDataset(),
+                                                                                                                      FullyConnectedParameters),
+                                                                                                              framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute function
-    Tensor dst = compute_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, 0);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, 0);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f32);
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
 
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall,
-                     SmallFullyConnectedLayerDataset() * boost::unit_test::data::make({ DataType::QS8 }) * boost::unit_test::data::xrange(4, 7),
-                     fc_set, dt, fixed_point_position)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEFullyConnectedLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallFullyConnectedLayerDataset(), FullyConnectedParameters),
+                                                                                                                 framework::dataset::make("DataType", DataType::F32)))
 {
-    // Compute function
-    Tensor dst = compute_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_qs8);
+    validate(Accessor(_target), _reference, tolerance_f32);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge,
-                     LargeFullyConnectedLayerDataset() * boost::unit_test::data::make({ DataType::QS8 }) * boost::unit_test::data::xrange(4, 7),
-                     fc_set, dt, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEFullyConnectedLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeFullyConnectedLayerDataset(), FullyConnectedParameters),
+                                                                                                               framework::dataset::make("DataType", DataType::F32)))
 {
-    // Compute function
-    Tensor dst = compute_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fully_connected_layer(fc_set.src_shape, fc_set.weights_shape, fc_set.bias_shape, fc_set.dst_shape, dt, fc_set.transpose_weights, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_qs8);
+    validate(Accessor(_target), _reference, tolerance_f32);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+template <typename T>
+using NEFullyConnectedLayerFixedPointFixture = FullyConnectedLayerValidationFixedPointFixture<Tensor, Accessor, NEFullyConnectedLayer, T, true>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// Testing for fixed point position [1,6) as reciprocal limits the maximum fixed point position to 5
+FIXTURE_DATA_TEST_CASE(RunSmall, NEFullyConnectedLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEFullyConnectedLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 14
+FIXTURE_DATA_TEST_CASE(RunSmall, NEFullyConnectedLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEFullyConnectedLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeFullyConnectedLayerDataset(),
+                       FullyConnectedParameters),
+                       framework::dataset::make("DataType",
+                                                DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/GEMM.cpp b/tests/validation/NEON/GEMM.cpp
index 0172dde..7844e51 100644
--- a/tests/validation/NEON/GEMM.cpp
+++ b/tests/validation/NEON/GEMM.cpp
@@ -21,183 +21,147 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "dataset/GEMMDataset.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEGEMM.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/LargeGEMMDataset.h"
+#include "tests/datasets/SmallGEMMDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/GEMMFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-const float tolerance_f32 = 1e-03f; /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
-const float tolerance_qs8 = 1.0f;   /**< Tolerance value for comparing reference's output against implementation's output for DataType::QS8 */
+constexpr AbsoluteTolerance<float> tolerance_f(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for floating point data types */
+constexpr AbsoluteTolerance<float> tolerance_q(1.0f);   /**< Tolerance value for comparing reference's output against implementation's output for fixed point data types */
 
-Tensor compute_gemm(const TensorShape &src_shape1, const TensorShape &src_shape2, const TensorShape &src_shape3,
-                    const TensorShape &out_shape, float alpha, float beta, DataType dt, int fixed_point_position = 0)
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
 {
-    // Create tensors
-    Tensor src1 = create_tensor(src_shape1, dt, 1, fixed_point_position);
-    Tensor src2 = create_tensor(src_shape2, dt, 1, fixed_point_position);
-    Tensor src3 = create_tensor(src_shape3, dt, 1, fixed_point_position);
-    Tensor dst  = create_tensor(out_shape, dt, 1, fixed_point_position);
-
-    // Create and configure function
-    NEGEMM gemm;
-    gemm.configure(&src1, &src2, &src3, &dst, alpha, beta);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    src3.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!src3.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    if(dt == DataType::F32)
-    {
-        std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
-        library->fill(NEAccessor(src1), distribution, 0);
-        library->fill(NEAccessor(src2), distribution, 1);
-        library->fill(NEAccessor(src3), distribution, 2);
-    }
-    else
-    {
-        library->fill_tensor_uniform(NEAccessor(src1), 0);
-        library->fill_tensor_uniform(NEAccessor(src2), 1);
-        library->fill_tensor_uniform(NEAccessor(src3), 2);
-    }
-
-    // Compute function
-    gemm.run();
-
-    return dst;
-}
+#ifdef ARM_COMPUTE_ENABLE_FP16
+    DataType::F16,
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
 } // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(GEMM)
+TEST_SUITE(NEON)
+TEST_SUITE(GEMM)
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration,
-                     SmallGEMMDataset() * boost::unit_test::data::make({ DataType::F32, DataType::QS8 }),
-                     gemm_set, dt)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallGEMMDataset(), datasets::LargeGEMMDataset()), CNNDataTypes),
+               shape_a, shape_b, shape_c, output_shape, alpha, beta, data_type)
 {
     // Set fixed point position data type allowed
-    int fixed_point_position = (dt == DataType::F32) ? 0 : 3;
+    const int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
 
     // Create tensors
-    Tensor src1 = create_tensor(gemm_set.shape_a, dt, 1, fixed_point_position);
-    Tensor src2 = create_tensor(gemm_set.shape_b, dt, 1, fixed_point_position);
-    Tensor src3 = create_tensor(gemm_set.shape_c, dt, 1, fixed_point_position);
-    Tensor dst  = create_tensor(gemm_set.shape_d, dt, 1, fixed_point_position);
+    Tensor a   = create_tensor<Tensor>(shape_a, data_type, 1, fixed_point_position);
+    Tensor b   = create_tensor<Tensor>(shape_b, data_type, 1, fixed_point_position);
+    Tensor c   = create_tensor<Tensor>(shape_c, data_type, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(output_shape, data_type, 1, fixed_point_position);
 
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(src3.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
+    ARM_COMPUTE_EXPECT(a.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(b.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(c.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
     NEGEMM gemm;
-    gemm.configure(&src1, &src2, &src3, &dst, gemm_set.alpha, gemm_set.beta);
-
-    // Validate valid region
-    const ValidRegion src1_valid_region = shape_to_valid_region(gemm_set.shape_a);
-    const ValidRegion src2_valid_region = shape_to_valid_region(gemm_set.shape_b);
-    const ValidRegion src3_valid_region = shape_to_valid_region(gemm_set.shape_c);
-    const ValidRegion dst_valid_region  = shape_to_valid_region(gemm_set.shape_d);
-
-    validate(src1.info()->valid_region(), src1_valid_region);
-    validate(src2.info()->valid_region(), src2_valid_region);
-    validate(src3.info()->valid_region(), src3_valid_region);
-    validate(dst.info()->valid_region(), dst_valid_region);
+    gemm.configure(&a, &b, &c, &dst, alpha, beta);
 }
 
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(SmallGEMM, SmallGEMMDataset() * boost::unit_test::data::make(DataType::F32),
-                     gemm_set, dt)
+template <typename T>
+using NEGEMMFixture = GEMMValidationFixture<Tensor, Accessor, NEGEMM, T>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMFixture<half>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallGEMMDataset(), framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt);
-
-    // Compute function
-    Tensor dst = compute_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f32);
+    validate(Accessor(_target), _reference, tolerance_f);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(LargeGEMM, LargeGEMMDataset() * boost::unit_test::data::make(DataType::F32),
-                     gemm_set, dt)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeGEMMDataset(), framework::dataset::make("DataType",
+                                                                                               DataType::F16)))
 {
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt);
-
-    // Compute function
-    Tensor dst = compute_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f32);
+    validate(Accessor(_target), _reference, tolerance_f);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
 
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(SmallGEMM, SmallGEMMDataset() * boost::unit_test::data::make(DataType::QS8) * boost::unit_test::data::xrange(1, 7),
-                     gemm_set, dt, fixed_point_position)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallGEMMDataset(), framework::dataset::make("DataType", DataType::F32)))
 {
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt, fixed_point_position);
-
-    // Compute function
-    Tensor dst = compute_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_qs8);
+    validate(Accessor(_target), _reference, tolerance_f);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(LargeGEMM, LargeGEMMDataset() * boost::unit_test::data::make(DataType::QS8) * boost::unit_test::data::xrange(1, 7),
-                     gemm_set, dt, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeGEMMDataset(), framework::dataset::make("DataType", DataType::F32)))
 {
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt, fixed_point_position);
-
-    // Compute function
-    Tensor dst = compute_gemm(gemm_set.shape_a, gemm_set.shape_b, gemm_set.shape_c, gemm_set.shape_d, gemm_set.alpha, gemm_set.beta, dt, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_qs8);
+    validate(Accessor(_target), _reference, tolerance_f);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+template <typename T>
+using NEGEMMFixedPointFixture = GEMMValidationFixedPointFixture<Tensor, Accessor, NEGEMM, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallGEMMDataset(),
+                                                                                                                     framework::dataset::make("DataType",
+                                                                                                                             DataType::QS8)),
+                                                                                                             framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeGEMMDataset(),
+                                                                                                                   framework::dataset::make("DataType",
+                                                                                                                           DataType::QS8)),
+                                                                                                           framework::dataset::make("FractionalBits", 1, 7)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallGEMMDataset(),
+                                                                                                                      framework::dataset::make("DataType",
+                                                                                                                              DataType::QS16)),
+                                                                                                              framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEGEMMFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeGEMMDataset(),
+                                                                                                                    framework::dataset::make("DataType",
+                                                                                                                            DataType::QS16)),
+                                                                                                            framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_q);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/Gaussian3x3.cpp b/tests/validation/NEON/Gaussian3x3.cpp
new file mode 100644
index 0000000..253c42d
--- /dev/null
+++ b/tests/validation/NEON/Gaussian3x3.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEGaussian3x3.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/Gaussian3x3Fixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr unsigned int filter_size = 3;              /** Size of the kernel/filter in number of elements. */
+constexpr BorderSize   border_size(filter_size / 2); /** Border size of the kernel/filter around its central element. */
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(Gaussian3x3)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+                                                                   datasets::BorderModes()),
+               shape, data_type, border_mode)
+{
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    NEGaussian3x3 gaussian3x3;
+    gaussian3x3.configure(&src, &dst, border_mode);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size);
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+    calculator.set_border_size(1);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-1);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst.info()->padding(), dst_padding);
+}
+
+template <typename T>
+using NEGaussian3x3Fixture = Gaussian3x3ValidationFixture<Tensor, Accessor, NEGaussian3x3, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEGaussian3x3Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::U8)),
+                                                                                                           datasets::BorderModes()))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEGaussian3x3Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                 DataType::U8)),
+                                                                                                         datasets::BorderModes()))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/Gaussian5x5.cpp b/tests/validation/NEON/Gaussian5x5.cpp
new file mode 100644
index 0000000..d110fae
--- /dev/null
+++ b/tests/validation/NEON/Gaussian5x5.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEGaussian5x5.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/Gaussian5x5Fixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+constexpr unsigned int filter_size = 5;              /** Size of the kernel/filter in number of elements. */
+constexpr BorderSize   border_size(filter_size / 2); /** Border size of the kernel/filter around its central element. */
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(Gaussian5x5)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+                                                                   datasets::BorderModes()),
+               shape, data_type, border_mode)
+{
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    NEGaussian5x5 gaussian5x5;
+    gaussian5x5.configure(&src, &dst, border_mode);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size);
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 16);
+    calculator.set_border_size(2);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_processed_elements(8);
+    calculator.set_access_offset(-2);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst.info()->padding(), dst_padding);
+}
+
+template <typename T>
+using NEGaussian5x5Fixture = Gaussian5x5ValidationFixture<Tensor, Accessor, NEGaussian5x5, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEGaussian5x5Fixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::U8)),
+                                                                                                           datasets::BorderModes()))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEGaussian5x5Fixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                 DataType::U8)),
+                                                                                                         datasets::BorderModes()))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/HarrisCorners.cpp b/tests/validation/NEON/HarrisCorners.cpp
new file mode 100644
index 0000000..6d66549
--- /dev/null
+++ b/tests/validation/NEON/HarrisCorners.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEHarrisCorners.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/NEON/ArrayAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/HarrisCornersFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+const auto use_fp16 = framework::dataset::make("UseFP16",
+{
+#ifdef ARM_COMPUTE_ENABLE_FP16
+    true,
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+    false
+});
+
+const auto data = combine(framework::dataset::make("GradientSize", { 3, 5, 7 }), combine(framework::dataset::make("BlockSize", { 3, 5, 7 }), combine(datasets::BorderModes(), use_fp16)));
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(HarrisCorners)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), data), framework::dataset::make("Format", Format::U8)), shape,
+               gradient_size, block_size, border_mode, use_fp16, format)
+{
+    std::mt19937                          gen(library->seed());
+    std::uniform_real_distribution<float> real_dist(0.f, 0.01f);
+
+    const float threshold   = real_dist(gen);
+    const float sensitivity = real_dist(gen);
+
+    constexpr float max_euclidean_distance = 30.f;
+    real_dist                              = std::uniform_real_distribution<float>(0.f, max_euclidean_distance);
+    const float min_dist                   = real_dist(gen);
+
+    // Generate a random constant value
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type_from_format(format));
+    src.info()->set_format(format);
+    KeyPointArray corners;
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create harris corners configure function
+    NEHarrisCorners harris_corners;
+    harris_corners.configure(&src, threshold, min_dist, sensitivity, gradient_size, block_size, &corners, border_mode, constant_border_value, use_fp16);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(gradient_size / 2);
+    calculator.set_access_offset(-gradient_size / 2);
+    calculator.set_accessed_elements(16);
+
+    const PaddingSize padding = calculator.required_padding();
+
+    validate(src.info()->padding(), padding);
+}
+
+template <typename T>
+using NEHarrisCornersFixture = HarrisCornersValidationFixture<Tensor, Accessor, KeyPointArray, NEHarrisCorners, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEHarrisCornersFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), data), framework::dataset::make("Format", Format::U8)))
+{
+    // Validate output
+    ArrayAccessor<KeyPoint> array(_target);
+    validate_keypoints(array.buffer(), array.buffer() + array.num_values(), _reference.begin(), _reference.end(), RelativeTolerance<float>(0.0001f));
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEHarrisCornersFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), data), framework::dataset::make("Format", Format::U8)))
+{
+    // Validate output
+    ArrayAccessor<KeyPoint> array(_target);
+    validate_keypoints(array.buffer(), array.buffer() + array.num_values(), _reference.begin(), _reference.end(), RelativeTolerance<float>(0.0001f));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/IntegralImage.cpp b/tests/validation/NEON/IntegralImage.cpp
index f94af43..efa1965 100644
--- a/tests/validation/NEON/IntegralImage.cpp
+++ b/tests/validation/NEON/IntegralImage.cpp
@@ -21,125 +21,66 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEIntegralImage.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/IntegralImageFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Neon integral image function.
- *
- * @param[in] shape Shape of the input and output tensors.
- *
- * @return Computed output tensor.
- */
-Tensor compute_integral_image(const TensorShape &shape)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(IntegralImage)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
 {
     // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U32);
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::U32);
 
-    // Create integral image configure function
-    NEIntegralImage integral_image;
-    integral_image.configure(&src, &dst);
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src), 0);
-
-    // Compute function
-    integral_image.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(IntegralImage)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, SmallShapes() + LargeShapes(), shape)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, DataType::U8);
-    Tensor dst = create_tensor(shape, DataType::U32);
-
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create integral image configure function
+    // Create and configure function
     NEIntegralImage integral_image;
     integral_image.configure(&src, &dst);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src.info()->valid_region(), valid_region);
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize src_padding(0, required_padding(shape.x(), 16), 0, 0);
-    const PaddingSize dst_padding(1, required_padding(shape.x(), 16), 0, 1);
+    const PaddingSize src_padding = PaddingCalculator(shape.x(), 16).required_padding();
+    const PaddingSize dst_padding(1, src_padding.right, 0, 1);
 
     validate(src.info()->padding(), src_padding);
     validate(dst.info()->padding(), dst_padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes(), shape)
+template <typename T>
+using NEIntegralImageFixture = IntegralImageValidationFixture<Tensor, Accessor, NEIntegralImage, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEIntegralImageFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                             DataType::U8)))
 {
-    // Compute function
-    Tensor dst = compute_integral_image(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_integral_image(shape);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEIntegralImageFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                           DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes(), shape)
-{
-    // Compute function
-    Tensor dst = compute_integral_image(shape);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_integral_image(shape);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/L2Normalize.cpp b/tests/validation/NEON/L2Normalize.cpp
new file mode 100644
index 0000000..ceffa6d
--- /dev/null
+++ b/tests/validation/NEON/L2Normalize.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEL2Normalize.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/L2NormalizeFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+RelativeTolerance<float> tolerance_f32(0.00001f);
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(L2Normalize)
+
+template <typename T>
+using NEL2NormalizeFixture = L2NormalizeValidationFixture<Tensor, Accessor, NEL2Normalize, T>;
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEL2NormalizeFixture<float>, framework::DatasetMode::PRECOMMIT,
+                       combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), framework::dataset::make("Epsilon", { 1e-12 })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEL2NormalizeFixture<float>, framework::DatasetMode::NIGHTLY,
+                       combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), framework::dataset::make("Epsilon", { 1e-12 })))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/MeanStdDev.cpp b/tests/validation/NEON/MeanStdDev.cpp
new file mode 100644
index 0000000..44f7178
--- /dev/null
+++ b/tests/validation/NEON/MeanStdDev.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/NEON/functions/NEMeanStdDev.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/MeanStdDevFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+RelativeTolerance<float> tolerance_rel_high_error(0.05f);
+RelativeTolerance<float> tolerance_rel_low_error(0.0005f);
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(MeanStdDev)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+
+    // Create output variables
+    float mean    = 0.f;
+    float std_dev = 0.f;
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create configure function
+    NEMeanStdDev mean_std_dev_image;
+    mean_std_dev_image.configure(&src, &mean, &std_dev);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+}
+
+template <typename T>
+using NEMeanStdDevFixture = MeanStdDevValidationFixture<Tensor, Accessor, NEMeanStdDev, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEMeanStdDevFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::U8)))
+{
+    // Validate mean output
+    validate(_target.first, _reference.first);
+
+    // Validate std_dev output
+    validate(_target.second, _reference.second, tolerance_rel_high_error);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEMeanStdDevFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                        DataType::U8)))
+{
+    // Validate mean output
+    validate(_target.first, _reference.first, tolerance_rel_low_error);
+
+    // Validate std_dev output
+    validate(_target.second, _reference.second, tolerance_rel_high_error);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/MinMaxLocation.cpp b/tests/validation/NEON/MinMaxLocation.cpp
new file mode 100644
index 0000000..367bb6a
--- /dev/null
+++ b/tests/validation/NEON/MinMaxLocation.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+
+#include "arm_compute/runtime/NEON/functions/NEMinMaxLocation.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/NEON/ArrayAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/MinMaxLocationFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(MinMaxLocation)
+
+template <typename T>
+using NEMinMaxLocationFixture = MinMaxLocationValidationFixture<Tensor, Accessor, Array<Coordinates2D>, ArrayAccessor<Coordinates2D>, NEMinMaxLocation, T>;
+
+void validate_configuration(const Tensor &src, TensorShape shape)
+{
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create output storage
+    int32_t            min{};
+    int32_t            max{};
+    Coordinates2DArray min_loc(shape.total_size());
+    Coordinates2DArray max_loc(shape.total_size());
+
+    // Create and configure function
+    NEMinMaxLocation min_max_loc;
+    min_max_loc.configure(&src, &min, &max, &min_loc, &max_loc);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 1).required_padding();
+    validate(src.info()->padding(), padding);
+}
+
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::U8)), shape, data_type)
+{
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    src.info()->set_format(Format::U8);
+
+    validate_configuration(src, shape);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEMinMaxLocationFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                              DataType::U8)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEMinMaxLocationFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::U8)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+TEST_SUITE_END() // U8
+
+TEST_SUITE(S16)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::S16)), shape, data_type)
+{
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    src.info()->set_format(Format::S16);
+
+    validate_configuration(src, shape);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEMinMaxLocationFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                              DataType::S16)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEMinMaxLocationFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::S16)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+TEST_SUITE_END() // S16
+
+TEST_SUITE(Float)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), framework::dataset::make("DataType", DataType::F32)), shape, data_type)
+{
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    src.info()->set_format(Format::F32);
+
+    validate_configuration(src, shape);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEMinMaxLocationFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::Small2DShapes(), framework::dataset::make("DataType",
+                                                                                                            DataType::F32)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEMinMaxLocationFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::Large2DShapes(), framework::dataset::make("DataType",
+                                                                                                          DataType::F32)))
+{
+    validate_min_max_loc(_target, _reference);
+}
+
+TEST_SUITE_END() // F32
+
+TEST_SUITE_END() // MinMaxLocation
+TEST_SUITE_END() // NEON
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/NonLinearFilter.cpp b/tests/validation/NEON/NonLinearFilter.cpp
new file mode 100644
index 0000000..541e870
--- /dev/null
+++ b/tests/validation/NEON/NonLinearFilter.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/NEON/functions/NENonLinearFilter.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/MatrixPatternDataset.h"
+#include "tests/datasets/NonLinearFilterFunctionDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/NonLinearFilterFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(NonLinearFilter)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), datasets::NonLinearFilterFunctions()),
+                                                                                   framework::dataset::make("MaskSize", { 3U, 5U })),
+                                                                           datasets::MatrixPatterns()),
+                                                                   datasets::BorderModes()),
+               shape, function, mask_size, pattern, border_mode)
+{
+    std::mt19937                           generator(library->seed());
+    std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
+    const uint8_t                          constant_border_value = distribution_u8(generator);
+
+    // Create the mask
+    uint8_t mask[mask_size * mask_size];
+    fill_mask_from_pattern(mask, mask_size, mask_size, pattern);
+    const auto half_mask_size = static_cast<int>(mask_size / 2);
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, DataType::U8);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::U8);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    NENonLinearFilter filter;
+    filter.configure(&src, &dst, function, mask_size, pattern, mask, border_mode, constant_border_value);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, BorderSize(half_mask_size));
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), ((MatrixPattern::OTHER == pattern) ? 1 : 8));
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(half_mask_size);
+
+    const PaddingSize write_padding = calculator.required_padding(PaddingCalculator::Option::EXCLUDE_BORDER);
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-half_mask_size);
+
+    const PaddingSize read_padding = calculator.required_padding(PaddingCalculator::Option::INCLUDE_BORDER);
+
+    validate(src.info()->padding(), read_padding);
+    validate(dst.info()->padding(), write_padding);
+}
+
+template <typename T>
+using NENonLinearFilterFixture = NonLinearFilterValidationFixture<Tensor, Accessor, NENonLinearFilter, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NENonLinearFilterFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(combine(datasets::SmallShapes(),
+                                                                                                                       datasets::NonLinearFilterFunctions()),
+                                                                                                                       framework::dataset::make("MaskSize", { 3U, 5U })),
+                                                                                                                       datasets::MatrixPatterns()),
+                                                                                                                       datasets::BorderModes()),
+                                                                                                               framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), _border_size));
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NENonLinearFilterFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(combine(datasets::LargeShapes(),
+                                                                                                                     datasets::NonLinearFilterFunctions()),
+                                                                                                                     framework::dataset::make("MaskSize", { 3U, 5U })),
+                                                                                                                     datasets::MatrixPatterns()),
+                                                                                                                     datasets::BorderModes()),
+                                                                                                             framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), _border_size));
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/NormalizationLayer.cpp b/tests/validation/NEON/NormalizationLayer.cpp
index ff791ef..e0098ad 100644
--- a/tests/validation/NEON/NormalizationLayer.cpp
+++ b/tests/validation/NEON/NormalizationLayer.cpp
@@ -21,132 +21,121 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TypePrinter.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
+#include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NENormalizationLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/NormalizationTypesDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/NormalizationLayerFixture.h"
 
-#include <random>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
-/** Define tolerance of the normalization layer depending on values data type.
- *
- * @param[in] dt Data type of the tensors' values.
- *
- * @return Tolerance depending on the data type.
- */
-float normalization_layer_tolerance(DataType dt)
-{
-    switch(dt)
-    {
-        case DataType::QS8:
-            return 2.0f;
-        case DataType::F32:
-            return 1e-05;
-        default:
-            return 0.f;
-    }
-}
+/** Tolerance for float operations */
+#ifdef ARM_COMPUTE_ENABLE_FP16
+constexpr AbsoluteTolerance<float> tolerance_f16(0.001f);
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+constexpr AbsoluteTolerance<float> tolerance_f32(0.00001f);
+/** Tolerance for fixed point operations */
+constexpr AbsoluteTolerance<int8_t>  tolerance_qs8(2);
+constexpr AbsoluteTolerance<int16_t> tolerance_qs16(4);
 
-/** Compute Neon normalization layer function.
- *
- * @param[in] shape                Shape of the input and output tensors.
- * @param[in] dt                   Data type of input and output tensors.
- * @param[in] norm_info            Normalization Layer information.
- * @param[in] fixed_point_position (Optional) Fixed point position that expresses the number of bits for the fractional part of the number when the tensor's data type is QS8 or QS16 (default = 0).
- *
- * @return Computed output tensor.
- */
-Tensor compute_normalization_layer(const TensorShape &shape, DataType dt, NormalizationLayerInfo norm_info, int fixed_point_position = 0)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape, dt, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, dt, 1, fixed_point_position);
-
-    // Create and configure function
-    NENormalizationLayer norm;
-    norm.configure(&src, &dst, norm_info);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    if(dt == DataType::QS8)
-    {
-        const int8_t one_fixed_point       = 1 << fixed_point_position;
-        const int8_t minus_one_fixed_point = -one_fixed_point;
-        library->fill_tensor_uniform(NEAccessor(src), 0, minus_one_fixed_point, one_fixed_point);
-    }
-    else
-    {
-        library->fill_tensor_uniform(NEAccessor(src), 0);
-    }
-
-    // Compute function
-    norm.run();
-
-    return dst;
-}
+/** Input data set. */
+const auto NormalizationDataset = combine(combine(combine(datasets::SmallShapes(), datasets::NormalizationTypes()), framework::dataset::make("NormalizationSize", 3, 9, 2)),
+                                          framework::dataset::make("Beta", { 0.5f, 1.f, 2.f }));
 } // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(NormalizationLayer)
+TEST_SUITE(NEON)
+TEST_SUITE(NormalizationLayer)
 
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall,
-                     SmallShapes() * DataType::F32 *NormalizationTypes() * boost::unit_test::data::xrange(3, 9, 2) * boost::unit_test::data::make({ 0.5f, 1.0f, 2.0f }),
-                     shape, dt, norm_type, norm_size, beta)
+template <typename T>
+using NENormalizationLayerFixture = NormalizationValidationFixture<Tensor, Accessor, NENormalizationLayer, T>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NENormalizationLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F16)))
 {
-    // Provide normalization layer information
-    NormalizationLayerInfo norm_info(norm_type, norm_size, 5, beta);
-
-    // Compute function
-    Tensor dst = compute_normalization_layer(shape, dt, norm_info);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_normalization_layer(shape, dt, norm_info);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, normalization_layer_tolerance(DataType::F32));
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall,
-                     SmallShapes() * DataType::QS8 *NormalizationTypes() * boost::unit_test::data::xrange(3, 7, 2) * (boost::unit_test::data::xrange(1, 6) * boost::unit_test::data::make({ 0.5f, 1.0f, 2.0f })),
-                     shape, dt, norm_type, norm_size, fixed_point_position, beta)
+FIXTURE_DATA_TEST_CASE(RunLarge, NENormalizationLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F16)))
 {
-    // Provide normalization layer information
-    NormalizationLayerInfo norm_info(norm_type, norm_size, 5, beta, 1.f);
-
-    // Compute function
-    Tensor dst = compute_normalization_layer(shape, dt, norm_info, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_normalization_layer(shape, dt, norm_info, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, normalization_layer_tolerance(DataType::QS8));
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NENormalizationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NENormalizationLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(NormalizationDataset, framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using NENormalizationLayerFixedPointFixture = NormalizationValidationFixedPointFixture<Tensor, Accessor, NENormalizationLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+// Testing for fixed point position [1,6) as reciprocal limits the maximum fixed point position to 5
+FIXTURE_DATA_TEST_CASE(RunSmall, NENormalizationLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs8);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NENormalizationLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS8)),
+                       framework::dataset::make("FractionalBits", 1, 6)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs8);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 14
+FIXTURE_DATA_TEST_CASE(RunSmall, NENormalizationLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NENormalizationLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(NormalizationDataset, framework::dataset::make("DataType",
+                       DataType::QS16)),
+                       framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/PixelWiseMultiplication.cpp b/tests/validation/NEON/PixelWiseMultiplication.cpp
deleted file mode 100644
index c6c2792..0000000
--- a/tests/validation/NEON/PixelWiseMultiplication.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
-#include "arm_compute/runtime/NEON/functions/NEPixelWiseMultiplication.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
-
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-/** Compute Neon arithmetic addition function.
- *
- * @param[in] shape                Shape of the input and output tensors.
- * @param[in] dt_in0               Data type of first input tensor.
- * @param[in] dt_in1               Data type of second input tensor.
- * @param[in] dt_out               Data type of the output tensor.
- * @param[in] scale                Non-negative scale.
- * @param[in] convert_policy       Overflow policy of the operation.
- * @param[in] rounding_policy      Rounding policy of the operation.
- * @param[in] fixed_point_position Fixed point position that expresses the number of bits for the fractional part of the number.
- *
- * @return Computed output tensor.
- */
-Tensor compute_pixel_wise_multiplication(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy,
-                                         int fixed_point_position = 0)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, dt_in0, 1, fixed_point_position);
-    Tensor src2 = create_tensor(shape, dt_in1, 1, fixed_point_position);
-    Tensor dst  = create_tensor(shape, dt_out, 1, fixed_point_position);
-
-    // Create and configure function
-    NEPixelWiseMultiplication multiply;
-    multiply.configure(&src1, &src2, &dst, scale, convert_policy, rounding_policy);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    src2.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!src2.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-    library->fill_tensor_uniform(NEAccessor(src2), 1);
-
-    // Compute function
-    multiply.run();
-
-    return dst;
-}
-
-void validate_configuration(const Tensor &src1, const Tensor &src2, Tensor &dst, TensorShape shape, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-{
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(src2.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEPixelWiseMultiplication multiply;
-    multiply.configure(&src1, &src2, &dst, scale, convert_policy, rounding_policy);
-
-    // Validate valid region
-    const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src1.info()->valid_region(), valid_region);
-    validate(src2.info()->valid_region(), valid_region);
-    validate(dst.info()->valid_region(), valid_region);
-
-    // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src1.info()->padding(), padding);
-    validate(src2.info()->padding(), padding);
-    validate(dst.info()->padding(), padding);
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(PixelWiseMultiplication)
-
-BOOST_AUTO_TEST_SUITE(U8)
-
-BOOST_AUTO_TEST_SUITE(Scale255)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * (1.f / 255.f) * ConvertPolicies()
-                     * RoundingPolicy::TO_NEAREST_UP,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    validate_configuration(src1, src2, dst, shape, scale, convert_policy, rounding_policy);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * (1.f / 255.f) * ConvertPolicies() * RoundingPolicy::TO_NEAREST_UP,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::U8, DataType::U8, DataType::U8, scale, convert_policy,
-                                                   rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::U8, DataType::U8,
-                                                                               DataType::U8, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    // Allow tolerance value of 1.f to counteract imprecision due to 32-bit float conversion
-    validate(NEAccessor(dst), ref_dst, 1.f, 0.f, std::numeric_limits<uint8_t>::max());
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * (1.f / 255.f) * ConvertPolicies() * RoundingPolicy::TO_NEAREST_UP,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::U8, DataType::U8, DataType::U8, scale, convert_policy,
-                                                   rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::U8, DataType::U8,
-                                                                               DataType::U8, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    // Allow tolerance value of 1.f to counteract imprecision due to 32-bit float conversion
-    validate(NEAccessor(dst), ref_dst, 1.f, 0.f, std::numeric_limits<uint8_t>::max());
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(ScaleOther)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ 1.f, 1.f / 32768.f })
-                     * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor src2 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    validate_configuration(src1, src2, dst, shape, scale, convert_policy, rounding_policy);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ 1.f, 1.f / 32768.f }) * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::U8, DataType::U8, DataType::U8, scale, convert_policy,
-                                                   rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::U8, DataType::U8,
-                                                                               DataType::U8, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ 1.f, 1.f / 32768.f }) * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::U8, DataType::U8, DataType::U8, scale, convert_policy,
-                                                   rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::U8, DataType::U8,
-                                                                               DataType::U8, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(S16)
-BOOST_AUTO_TEST_SUITE(Scale255)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * (1.f / 255.f) * ConvertPolicies()
-                     * RoundingPolicy::TO_NEAREST_UP,
-                     shape, dt, scale, convert_policy, rounding_policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, dt);
-    Tensor src2 = create_tensor(shape, DataType::S16);
-    Tensor dst  = create_tensor(shape, DataType::S16);
-
-    validate_configuration(src1, src2, dst, shape, scale, convert_policy, rounding_policy);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * (1.f / 255.f) * ConvertPolicies()
-                     * RoundingPolicy::TO_NEAREST_UP,
-                     shape, dt, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    // Allow tolerance value of 2.f to counteract imprecision due to 32-bit float conversion
-    validate(NEAccessor(dst), ref_dst, 2.f, 0.f, std::numeric_limits<int16_t>::max());
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * (1.f / 255.f) * ConvertPolicies()
-                     * RoundingPolicy::TO_NEAREST_UP,
-                     shape, dt, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16,
-                                                                               scale, convert_policy, rounding_policy);
-
-    // Validate output
-    // Allow tolerance value of 2.f to counteract imprecision due to 32-bit float conversion
-    validate(NEAccessor(dst), ref_dst, 2.f, 0.f, std::numeric_limits<int16_t>::max());
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(ScaleOther)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ 1.f, 1.f / 32768.f })
-                     * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, dt, scale, convert_policy, rounding_policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, dt);
-    Tensor src2 = create_tensor(shape, DataType::S16);
-    Tensor dst  = create_tensor(shape, DataType::S16);
-
-    validate_configuration(src1, src2, dst, shape, scale, convert_policy, rounding_policy);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ 1.f, 1.f / 32768.f }) * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, dt, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ DataType::U8, DataType::S16 }) * boost::unit_test::data::make({ 1.f, 1.f / 32768.f }) * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, dt, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, dt, DataType::S16, DataType::S16,
-                                                                               scale, convert_policy, rounding_policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(F32)
-BOOST_AUTO_TEST_SUITE(Scale255)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * (1.f / 255.f) * ConvertPolicies()
-                     * RoundingPolicy::TO_NEAREST_UP,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::F32);
-    Tensor src2 = create_tensor(shape, DataType::F32);
-    Tensor dst  = create_tensor(shape, DataType::F32);
-
-    validate_configuration(src1, src2, dst, shape, scale, convert_policy, rounding_policy);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * (1.f / 255.f) * ConvertPolicies()
-                     * RoundingPolicy::TO_NEAREST_UP,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    // Allow tolerance value of 1.f to counteract imprecision due to 32-bit float conversion
-    validate(NEAccessor(dst), ref_dst, 1.f, 0.f, std::numeric_limits<int16_t>::max());
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * (1.f / 255.f) * ConvertPolicies()
-                     * RoundingPolicy::TO_NEAREST_UP,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32,
-                                                                               scale, convert_policy, rounding_policy);
-
-    // Validate output
-    // Allow tolerance value of 1.f to counteract imprecision due to 32-bit float conversion
-    validate(NEAccessor(dst), ref_dst, 1.f, 0.f, std::numeric_limits<int16_t>::max());
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(ScaleOther)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * boost::unit_test::data::make({ 1.f, 1.f / 32768.f })
-                     * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::F32);
-    Tensor src2 = create_tensor(shape, DataType::F32);
-    Tensor dst  = create_tensor(shape, DataType::F32);
-
-    validate_configuration(src1, src2, dst, shape, scale, convert_policy, rounding_policy);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * boost::unit_test::data::make({ 1.f, 1.f / 32768.f }) * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32, scale, convert_policy, rounding_policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ 1.f, 1.f / 32768.f }) * ConvertPolicies()
-                     * RoundingPolicy::TO_ZERO,
-                     shape, scale, convert_policy, rounding_policy)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32, scale, convert_policy, rounding_policy);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pixel_wise_multiplication(shape, DataType::F32, DataType::F32, DataType::F32,
-                                                                               scale, convert_policy, rounding_policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(QS8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * DataType::QS8 *ConvertPolicies() * RoundingPolicy::TO_ZERO * boost::unit_test::data::xrange<int>(1, 7),
-                     shape, dt, convert_policy, rounding_policy, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_pixel_wise_multiplication(shape, dt, dt, dt, 1.f, convert_policy, rounding_policy, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_fixed_point_pixel_wise_multiplication(shape, dt, dt, dt, 1.f, fixed_point_position, convert_policy, rounding_policy);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/Pooling/PoolingLayer.cpp b/tests/validation/NEON/Pooling/PoolingLayer.cpp
deleted file mode 100644
index b15ad1c..0000000
--- a/tests/validation/NEON/Pooling/PoolingLayer.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TypePrinter.h"
-#include "arm_compute/runtime/NEON/functions/NEPoolingLayer.h"
-#include "tests/dataset/PoolingLayerDataset.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include <iostream>
-#include <random>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-const float tolerance_q = 0;     /**< Tolerance value for comparing reference's output against implementation's output for quantized input */
-const float tolerance_f = 1e-05; /**< Tolerance value for comparing reference's output against implementation's output for float input */
-
-/** Compute Neon pooling layer function.
- *
- * @param[in] shape     Shape of the input and output tensors.
- * @param[in] dt        Data type of input and output tensors.
- * @param[in] pool_info Pooling Layer information.
- *
- * @return Computed output tensor.
- */
-Tensor compute_pooling_layer(const TensorShape &shape_in, const TensorShape &shape_out, DataType dt, PoolingLayerInfo pool_info, int fixed_point_position = 0)
-{
-    // Create tensors
-    Tensor src = create_tensor(shape_in, dt, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape_out, dt, 1, fixed_point_position);
-
-    // Create and configure function
-    NEPoolingLayer pool;
-    pool.configure(&src, &dst, pool_info);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    int min = 0;
-    int max = 0;
-    switch(dt)
-    {
-        case DataType::F32:
-            min = -1;
-            max = 1;
-            break;
-        case DataType::QS8:
-            min = -(1 << fixed_point_position);
-            max = (1 << fixed_point_position);
-            break;
-        default:
-            ARM_COMPUTE_ERROR("DataType not supported.");
-    }
-    std::uniform_real_distribution<> distribution(min, max);
-    library->fill(NEAccessor(src), distribution, 0);
-
-    // Compute function
-    pool.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(Pooling)
-BOOST_AUTO_TEST_SUITE(PoolingLayer)
-
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RandomDataset,
-                     RandomPoolingLayerDataset() * boost::unit_test::data::make(DataType::F32),
-                     obj, dt)
-{
-    // Compute function
-    Tensor dst = compute_pooling_layer(obj.src_shape, obj.dst_shape, dt, obj.info);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pooling_layer(obj.src_shape, obj.dst_shape, dt, obj.info);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_f, 0);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(Quantized)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RandomDataset,
-                     RandomPoolingLayerDataset() * boost::unit_test::data::make(DataType::QS8) * boost::unit_test::data::xrange(1, 5),
-                     obj, dt, fixed_point_position)
-{
-    // Compute function
-    Tensor dst = compute_pooling_layer(obj.src_shape, obj.dst_shape, dt, obj.info, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_pooling_layer(obj.src_shape, obj.dst_shape, dt, obj.info, fixed_point_position);
-
-    // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_q, 0);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/NEON/PoolingLayer.cpp b/tests/validation/NEON/PoolingLayer.cpp
new file mode 100644
index 0000000..27f6aab
--- /dev/null
+++ b/tests/validation/NEON/PoolingLayer.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEPoolingLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/PoolingTypesDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/PoolingLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Input data set for float data types */
+const auto PoolingLayerDatasetFP = combine(combine(datasets::PoolingTypes(), framework::dataset::make("PoolingSize", { 2, 3, 7 })),
+                                           framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) }));
+
+/** Input data set for quantized data types */
+const auto PoolingLayerDatasetQS = combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }), framework::dataset::make("PoolingSize", { 2, 3 })),
+                                           framework::dataset::make("PadStride", { PadStrideInfo(1, 1, 0, 0), PadStrideInfo(2, 1, 0, 0), PadStrideInfo(1, 2, 1, 1), PadStrideInfo(2, 2, 1, 0) }));
+
+constexpr AbsoluteTolerance<float> tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for float types */
+#ifdef ARM_COMPUTE_ENABLE_FP16
+constexpr AbsoluteTolerance<float> tolerance_f16(0.01f); /**< Tolerance value for comparing reference's output against implementation's output for float types */
+#endif                                                   /* ARM_COMPUTE_ENABLE_FP16 */
+constexpr AbsoluteTolerance<float> tolerance_qs8(0);     /**< Tolerance value for comparing reference's output against implementation's output for quantized input */
+constexpr AbsoluteTolerance<float> tolerance_qs16(0);    /**< Tolerance value for comparing reference's output against implementation's output for quantized input */
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(PoolingLayer)
+
+template <typename T>
+using NEPoolingLayerFixture = PoolingLayerValidationFixture<Tensor, Accessor, NEPoolingLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerFixture<float>, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), combine(PoolingLayerDatasetFP, framework::dataset::make("DataType",
+                                                                                                    DataType::F32))))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEPoolingLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), combine(PoolingLayerDatasetFP, framework::dataset::make("DataType",
+                                                                                                        DataType::F32))))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerFixture<half>, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), combine(PoolingLayerDatasetFP,
+                                                                                                   framework::dataset::make("DataType", DataType::F16))))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEPoolingLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), combine(PoolingLayerDatasetFP,
+                                                                                                       framework::dataset::make("DataType", DataType::F16))))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f16);
+}
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+TEST_SUITE_END()
+
+template <typename T>
+using NEPoolingLayerFixedPointFixture = PoolingLayerValidationFixedPointFixture<Tensor, Accessor, NEPoolingLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerFixedPointFixture<int8_t>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                       framework::dataset::make("DataType", DataType::QS8))),
+                                                                                                               framework::dataset::make("FractionalBits", 1, 5)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs8);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEPoolingLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                   framework::dataset::make("DataType", DataType::QS8))),
+                                                                                                                   framework::dataset::make("FractionalBits", 1, 5)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs8);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(QS16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerFixedPointFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(datasets::SmallShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                        framework::dataset::make("DataType", DataType::QS16))),
+                                                                                                                framework::dataset::make("FractionalBits", 1, 13)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEPoolingLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), combine(PoolingLayerDatasetQS,
+                                                                                                                    framework::dataset::make("DataType", DataType::QS16))),
+                                                                                                                    framework::dataset::make("FractionalBits", 1, 13)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_qs16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/QuantizationLayer.cpp b/tests/validation/NEON/QuantizationLayer.cpp
new file mode 100644
index 0000000..26657c4
--- /dev/null
+++ b/tests/validation/NEON/QuantizationLayer.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEQuantizationLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/QuantizationLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for quantization */
+constexpr AbsoluteTolerance<uint8_t> tolerance_u8(1);
+
+const auto QuantizationShapes = concat(concat(concat(datasets::Small3DShapes(),
+                                                     datasets::Large3DShapes()),
+                                              datasets::Small4DShapes()),
+                                       datasets::Large4DShapes());
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(QuantizationLayer)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(QuantizationShapes, framework::dataset::make("DataType", DataType::F32)), shape, data_type)
+{
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, DataType::U8);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    NEQuantizationLayer quant_layer;
+    quant_layer.configure(&src, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(src.info()->valid_region(), valid_region);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 8).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+
+template <typename T>
+using NEQuantizationLayerFixture = QuantizationValidationFixture<Tensor, Accessor, NEQuantizationLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEQuantizationLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(concat(datasets::Small3DShapes(), datasets::Small4DShapes()),
+                                                                                                               framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_u8);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEQuantizationLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(concat(datasets::Large3DShapes(), datasets::Large4DShapes()),
+                                                                                                             framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_u8);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/ReductionOperation.cpp b/tests/validation/NEON/ReductionOperation.cpp
new file mode 100644
index 0000000..cf603c6
--- /dev/null
+++ b/tests/validation/NEON/ReductionOperation.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEReductionOperation.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ReductionOperationDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ReductionOperationFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Tolerance for float operations */
+RelativeTolerance<float> tolerance_f32(0.00001f);
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(ReductionOperation)
+
+template <typename T>
+using NEReductionOperationFixture = ReductionOperationValidationFixture<Tensor, Accessor, NEReductionOperation, T>;
+
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEReductionOperationFixture<float>, framework::DatasetMode::PRECOMMIT,
+                       combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), datasets::ReductionOperations()))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEReductionOperationFixture<float>, framework::DatasetMode::NIGHTLY,
+                       combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), framework::dataset::make("Axis", { 0 })), datasets::ReductionOperations()))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/ReshapeLayer.cpp b/tests/validation/NEON/ReshapeLayer.cpp
new file mode 100644
index 0000000..0ad6511
--- /dev/null
+++ b/tests/validation/NEON/ReshapeLayer.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEReshapeLayer.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ReshapeLayerDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ReshapeLayerFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(ReshapeLayer)
+
+template <typename T>
+using NEReshapeLayerFixture = ReshapeLayerValidationFixture<Tensor, Accessor, NEReshapeLayer, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(F32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEReshapeLayerFixture<float>, framework::DatasetMode::ALL, combine(datasets::SmallReshapeLayerDataset(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Integer)
+TEST_SUITE(S8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEReshapeLayerFixture<int8_t>, framework::DatasetMode::ALL, combine(datasets::SmallReshapeLayerDataset(), framework::dataset::make("DataType", DataType::S8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(S16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEReshapeLayerFixture<int16_t>, framework::DatasetMode::ALL, combine(datasets::SmallReshapeLayerDataset(), framework::dataset::make("DataType", DataType::S16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/SYSTEM/AlexNet.cpp b/tests/validation/NEON/SYSTEM/AlexNet.cpp
new file mode 100644
index 0000000..3fa19e4
--- /dev/null
+++ b/tests/validation/NEON/SYSTEM/AlexNet.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/NEON/functions/NEActivationLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEConvolutionLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEDirectConvolutionLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h"
+#include "arm_compute/runtime/NEON/functions/NENormalizationLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEPoolingLayer.h"
+#include "arm_compute/runtime/NEON/functions/NESoftmaxLayer.h"
+#include "arm_compute/runtime/SubTensor.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/networks/AlexNetNetwork.h"
+#include "tests/validation/Validation.h"
+
+#include <string>
+#include <vector>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+using NEAlexNetModel = networks::AlexNetNetwork<ITensor,
+      Tensor,
+      SubTensor,
+      Accessor,
+      NEActivationLayer,
+      NEConvolutionLayer,
+      NEDirectConvolutionLayer,
+      NEFullyConnectedLayer,
+      NENormalizationLayer,
+      NEPoolingLayer,
+      NESoftmaxLayer>;
+std::vector<unsigned int> compute_alexnet(DataType dt, unsigned int batches, std::string input_file)
+{
+    std::vector<std::string> weight_files = { "cnn_data/alexnet_model/conv1_w.npy",
+                                              "cnn_data/alexnet_model/conv2_w.npy",
+                                              "cnn_data/alexnet_model/conv3_w.npy",
+                                              "cnn_data/alexnet_model/conv4_w.npy",
+                                              "cnn_data/alexnet_model/conv5_w.npy",
+                                              "cnn_data/alexnet_model/fc6_w.npy",
+                                              "cnn_data/alexnet_model/fc7_w.npy",
+                                              "cnn_data/alexnet_model/fc8_w.npy"
+                                            };
+
+    std::vector<std::string> bias_files = { "cnn_data/alexnet_model/conv1_b.npy",
+                                            "cnn_data/alexnet_model/conv2_b.npy",
+                                            "cnn_data/alexnet_model/conv3_b.npy",
+                                            "cnn_data/alexnet_model/conv4_b.npy",
+                                            "cnn_data/alexnet_model/conv5_b.npy",
+                                            "cnn_data/alexnet_model/fc6_b.npy",
+                                            "cnn_data/alexnet_model/fc7_b.npy",
+                                            "cnn_data/alexnet_model/fc8_b.npy"
+                                          };
+    NEAlexNetModel network{};
+
+    network.init(dt, 4, batches);
+    network.build();
+    network.allocate();
+    network.fill(weight_files, bias_files);
+    network.feed(std::move(input_file));
+    network.run();
+
+    return network.get_classifications();
+}
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(SYSTEM_TESTS)
+
+TEST_CASE(AlexNet, framework::DatasetMode::PRECOMMIT)
+{
+    // Compute alexnet
+    std::vector<unsigned int> classified_labels = compute_alexnet(DataType::F32, 1, "cnn_data/imagenet_data/cat.npy");
+
+    // Expected labels
+    std::vector<unsigned int> expected_labels = { 281 };
+
+    // Validate labels
+    validate(classified_labels, expected_labels);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/SYSTEM/LeNet5.cpp b/tests/validation/NEON/SYSTEM/LeNet5.cpp
new file mode 100644
index 0000000..95a82a6
--- /dev/null
+++ b/tests/validation/NEON/SYSTEM/LeNet5.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/runtime/NEON/functions/NEActivationLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEConvolutionLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEFullyConnectedLayer.h"
+#include "arm_compute/runtime/NEON/functions/NEPoolingLayer.h"
+#include "arm_compute/runtime/NEON/functions/NESoftmaxLayer.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/networks/LeNet5Network.h"
+#include "tests/validation/Validation.h"
+
+#include <string>
+#include <vector>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+using NELeNet5Model = networks::LeNet5Network<Tensor,
+      Accessor,
+      NEActivationLayer,
+      NEConvolutionLayer,
+      NEFullyConnectedLayer,
+      NEPoolingLayer,
+      NESoftmaxLayer>;
+std::vector<unsigned int> compute_lenet5(unsigned int batches, std::string input_file)
+{
+    std::vector<std::string> weight_files = { "cnn_data/lenet_model/conv1_w.npy",
+                                              "cnn_data/lenet_model/conv2_w.npy",
+                                              "cnn_data/lenet_model/ip1_w.npy",
+                                              "cnn_data/lenet_model/ip2_w.npy"
+                                            };
+
+    std::vector<std::string> bias_files = { "cnn_data/lenet_model/conv1_b.npy",
+                                            "cnn_data/lenet_model/conv2_b.npy",
+                                            "cnn_data/lenet_model/ip1_b.npy",
+                                            "cnn_data/lenet_model/ip2_b.npy"
+                                          };
+    NELeNet5Model network{};
+    network.init(batches);
+    network.build();
+    network.allocate();
+    network.fill(weight_files, bias_files);
+    network.feed(std::move(input_file));
+    network.run();
+
+    return network.get_classifications();
+}
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(SYSTEM_TESTS)
+
+TEST_CASE(LeNet5, framework::DatasetMode::PRECOMMIT)
+{
+    // Compute alexnet
+    std::vector<unsigned int> classified_labels = compute_lenet5(10, "cnn_data/mnist_data/input10.npy");
+
+    // Expected labels
+    std::vector<unsigned int> expected_labels = { 7, 2, 1, 0, 4, 1, 4, 9, 5, 9 };
+
+    // Validate labels
+    validate(classified_labels, expected_labels);
+}
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/Scale.cpp b/tests/validation/NEON/Scale.cpp
new file mode 100644
index 0000000..aa7dc67
--- /dev/null
+++ b/tests/validation/NEON/Scale.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Helpers.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NEScale.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/InterpolationPolicyDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Helpers.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ScaleFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+namespace
+{
+/** Scale data types */
+const auto ScaleDataTypes = framework::dataset::make("DataType",
+{
+    DataType::U8,
+    DataType::S16,
+    DataType::F32,
+});
+
+/** Tolerance */
+constexpr AbsoluteTolerance<uint8_t> tolerance_u8(1);
+constexpr AbsoluteTolerance<int16_t> tolerance_s16(1);
+RelativeTolerance<float>             tolerance_f32(0.01);
+
+constexpr float tolerance_num_s16 = 0.01f;
+constexpr float tolerance_num_f32 = 0.01f;
+} // namespace
+
+TEST_SUITE(NEON)
+TEST_SUITE(Scale)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), ScaleDataTypes),
+                                                                           framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                   datasets::BorderModes()),
+               shape, data_type, policy, border_mode)
+{
+    std::mt19937                          generator(library->seed());
+    std::uniform_real_distribution<float> distribution_float(0.25, 2);
+    const float                           scale_x               = distribution_float(generator);
+    const float                           scale_y               = distribution_float(generator);
+    uint8_t                               constant_border_value = 0;
+    if(border_mode == BorderMode::CONSTANT)
+    {
+        std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
+        constant_border_value = distribution_u8(generator);
+    }
+
+    // Create tensors
+    Tensor      src = create_tensor<Tensor>(shape, data_type);
+    TensorShape shape_scaled(shape);
+    shape_scaled.set(0, shape[0] * scale_x);
+    shape_scaled.set(1, shape[1] * scale_y);
+    Tensor dst = create_tensor<Tensor>(shape_scaled, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create and configure function
+    NEScale nescale;
+    nescale.configure(&src, &dst, policy, border_mode, constant_border_value);
+
+    // Validate valid region
+    const ValidRegion dst_valid_region = calculate_valid_region_scale(*(src.info()), shape_scaled, policy, BorderSize(1), (border_mode == BorderMode::UNDEFINED));
+
+    validate(dst.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape_scaled.x(), 16);
+    calculator.set_border_mode(border_mode);
+
+    const PaddingSize read_padding(1);
+    const PaddingSize write_padding = calculator.required_padding(PaddingCalculator::Option::EXCLUDE_BORDER);
+    validate(src.info()->padding(), read_padding);
+    validate(dst.info()->padding(), write_padding);
+}
+
+template <typename T>
+using NEScaleFixture = ScaleValidationFixture<Tensor, Accessor, NEScale, T>;
+
+TEST_SUITE(Float)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                             DataType::F32)),
+                                                                                                     framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                             datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo  src_info(_shape, 1, _data_type);
+    ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                 DataType::F32)),
+                                                                                                         framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                                 datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo  src_info(_shape, 1, _data_type);
+    ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(Accessor(_target), _reference, valid_region, tolerance_f32, tolerance_num_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE(Integer)
+TEST_SUITE(U8)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                               DataType::U8)),
+                                                                                                       framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                               datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo  src_info(_shape, 1, _data_type);
+    ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(Accessor(_target), _reference, valid_region, tolerance_u8);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::U8)),
+                                                                                                           framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                                   datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo  src_info(_shape, 1, _data_type);
+    ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(Accessor(_target), _reference, valid_region, tolerance_u8);
+}
+TEST_SUITE_END()
+TEST_SUITE(S16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NEScaleFixture<int16_t>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                               DataType::S16)),
+                                                                                                       framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                               datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo  src_info(_shape, 1, _data_type);
+    ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(Accessor(_target), _reference, valid_region, tolerance_s16, tolerance_num_s16);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NEScaleFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::S16)),
+                                                                                                           framework::dataset::make("InterpolationPolicy", { InterpolationPolicy::NEAREST_NEIGHBOR, InterpolationPolicy::BILINEAR })),
+                                                                                                   datasets::BorderModes()))
+{
+    //Create valid region
+    TensorInfo  src_info(_shape, 1, _data_type);
+    ValidRegion valid_region = calculate_valid_region_scale(src_info, _reference.shape(), _policy, BorderSize(1), (_border_mode == BorderMode::UNDEFINED));
+
+    // Validate output
+    validate(Accessor(_target), _reference, valid_region, tolerance_s16, tolerance_num_s16);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/Sobel.cpp b/tests/validation/NEON/Sobel.cpp
new file mode 100644
index 0000000..99f9e1f
--- /dev/null
+++ b/tests/validation/NEON/Sobel.cpp
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NESobel3x3.h"
+#include "arm_compute/runtime/NEON/functions/NESobel5x5.h"
+#include "arm_compute/runtime/NEON/functions/NESobel7x7.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/BorderModeDataset.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/SobelFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(Sobel)
+
+TEST_SUITE(W3x3)
+using NESobel3x3Fixture = SobelValidationFixture<Tensor, Accessor, NESobel3x3, uint8_t, int16_t>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                   Format::U8)),
+               shape, border_mode, format)
+{
+    // Generate a random constant value
+    std::mt19937                           gen(library->seed());
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    Tensor src   = create_tensor<Tensor>(shape, data_type_from_format(format));
+    Tensor dst_x = create_tensor<Tensor>(shape, DataType::S16);
+    Tensor dst_y = create_tensor<Tensor>(shape, DataType::S16);
+
+    src.info()->set_format(format);
+    dst_x.info()->set_format(Format::S16);
+    dst_y.info()->set_format(Format::S16);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create sobel 3x3 configure function
+    NESobel3x3 sobel;
+    sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
+
+    // Validate valid region
+    constexpr BorderSize border_size{ 1 };
+    const ValidRegion    dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, border_size);
+
+    validate(dst_x.info()->valid_region(), dst_valid_region);
+    validate(dst_y.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(1);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-1);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst_x.info()->padding(), dst_padding);
+    validate(dst_y.info()->padding(), dst_padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NESobel3x3Fixture, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                               Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(Accessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(Accessor(_target.second), _reference.second, valid_region_y);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NESobel3x3Fixture, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                             Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(Accessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(1));
+    validate(Accessor(_target.second), _reference.second, valid_region_y);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(W5x5)
+using NESobel5x5Fixture = SobelValidationFixture<Tensor, Accessor, NESobel5x5, uint8_t, int16_t>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                   Format::U8)),
+               shape, border_mode, format)
+{
+    // Generate a random constant value
+    std::mt19937                           gen(library->seed());
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    Tensor src   = create_tensor<Tensor>(shape, data_type_from_format(format));
+    Tensor dst_x = create_tensor<Tensor>(shape, DataType::S16);
+    Tensor dst_y = create_tensor<Tensor>(shape, DataType::S16);
+
+    src.info()->set_format(format);
+    dst_x.info()->set_format(Format::S16);
+    dst_y.info()->set_format(Format::S16);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create sobel 5x5 configure function
+    NESobel5x5 sobel;
+    sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
+
+    // Validate valid region
+    constexpr BorderSize border_size{ 2 };
+    const ValidRegion    dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, border_size);
+
+    validate(dst_x.info()->valid_region(), dst_valid_region);
+    validate(dst_y.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 16);
+
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(2);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_processed_elements(8);
+    calculator.set_access_offset(-2);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst_x.info()->padding(), dst_padding);
+    validate(dst_y.info()->padding(), dst_padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NESobel5x5Fixture, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                               Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(Accessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(Accessor(_target.second), _reference.second, valid_region_y);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NESobel5x5Fixture, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                             Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(Accessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(2));
+    validate(Accessor(_target.second), _reference.second, valid_region_y);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(W7x7)
+using NESobel7x7Fixture = SobelValidationFixture<Tensor, Accessor, NESobel7x7, uint8_t, int32_t>;
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::Small2DShapes(), datasets::Large2DShapes()), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                   Format::U8)),
+               shape, border_mode, format)
+{
+    // Generate a random constant value
+    std::mt19937                           gen(library->seed());
+    std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+    const uint8_t                          constant_border_value = int_dist(gen);
+
+    // Create tensors
+    Tensor src   = create_tensor<Tensor>(shape, data_type_from_format(format));
+    Tensor dst_x = create_tensor<Tensor>(shape, DataType::S32);
+    Tensor dst_y = create_tensor<Tensor>(shape, DataType::S32);
+
+    src.info()->set_format(format);
+    dst_x.info()->set_format(Format::S32);
+    dst_y.info()->set_format(Format::S32);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+    // Create sobel 7x7 configure function
+    NESobel7x7 sobel;
+    sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
+
+    // Validate valid region
+    constexpr BorderSize border_size{ 3 };
+    const ValidRegion    dst_valid_region = shape_to_valid_region(shape, border_mode == BorderMode::UNDEFINED, border_size);
+
+    validate(dst_x.info()->valid_region(), dst_valid_region);
+    validate(dst_y.info()->valid_region(), dst_valid_region);
+
+    // Validate padding
+    PaddingCalculator calculator(shape.x(), 8);
+
+    calculator.set_border_mode(border_mode);
+    calculator.set_border_size(3);
+
+    const PaddingSize dst_padding = calculator.required_padding();
+
+    calculator.set_accessed_elements(16);
+    calculator.set_access_offset(-3);
+
+    const PaddingSize src_padding = calculator.required_padding();
+
+    validate(src.info()->padding(), src_padding);
+    validate(dst_x.info()->padding(), dst_padding);
+    validate(dst_y.info()->padding(), dst_padding);
+}
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NESobel7x7Fixture, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::Small2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                               Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(Accessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(Accessor(_target.second), _reference.second, valid_region_y);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NESobel7x7Fixture, framework::DatasetMode::NIGHTLY, combine(combine(datasets::Large2DShapes(), datasets::BorderModes()), framework::dataset::make("Format",
+                                                                                             Format::U8)))
+{
+    // Validate output
+    ValidRegion valid_region_x = shape_to_valid_region(_reference.first.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(Accessor(_target.first), _reference.first, valid_region_x);
+
+    ValidRegion valid_region_y = shape_to_valid_region(_reference.second.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(3));
+    validate(Accessor(_target.second), _reference.second, valid_region_y);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/SoftmaxLayer.cpp b/tests/validation/NEON/SoftmaxLayer.cpp
index f5c7a21..5ede321 100644
--- a/tests/validation/NEON/SoftmaxLayer.cpp
+++ b/tests/validation/NEON/SoftmaxLayer.cpp
@@ -21,100 +21,61 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
 #include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NESoftmaxLayer.h"
 #include "arm_compute/runtime/Tensor.h"
 #include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/SoftmaxLayerFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
 namespace
 {
 /** Tolerance for float operations */
-const float tolerance = 0.000001f;
+constexpr AbsoluteTolerance<float> tolerance_f32(0.000001f);
+#ifdef ARM_COMPUTE_ENABLE_FP16
+constexpr AbsoluteTolerance<float> tolerance_f16(0.0001f);
+#endif /* ARM_COMPUTE_ENABLE_FP16*/
 /** Tolerance for fixed point operations */
-const float tolerance_fixed_point = 2.f;
+constexpr AbsoluteTolerance<int16_t> tolerance_fixed_point(2);
 
-/** Compute Neon softmax layer function.
- *
- * @param[in] shape                Shape of the input and output tensors.
- * @param[in] dt                   Shape Data type of tensors.
- * @param[in] fixed_point_position (Optional) Number of bits for the fractional part of fixed point numbers.
- *
- * @return Computed output tensor.
- */
-Tensor compute_softmax_layer(const TensorShape &shape, DataType dt, int fixed_point_position = 0)
+/** CNN data types */
+const auto CNNDataTypes = framework::dataset::make("DataType",
 {
-    // Create tensors
-    Tensor src = create_tensor(shape, dt, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, dt, 1, fixed_point_position);
-
-    // Create and configure function
-    NESoftmaxLayer smx_layer;
-    smx_layer.configure(&src, &dst);
-
-    // Allocate tensors
-    src.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    if(arm_compute::is_data_type_float(dt))
-    {
-        std::uniform_real_distribution<> distribution(-10, 10);
-        library->fill(NEAccessor(src), distribution, 0);
-    }
-    else
-    {
-        int                             one_fixed = 1 << fixed_point_position;
-        std::uniform_int_distribution<> distribution(-one_fixed, one_fixed);
-        library->fill(NEAccessor(src), distribution, 0);
-    }
-
-    // Compute function
-    smx_layer.run();
-
-    return dst;
-}
+#ifdef ARM_COMPUTE_ENABLE_FP16
+    DataType::F16,
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
+    DataType::F32,
+    DataType::QS8,
+    DataType::QS16,
+});
 } // namespace
 
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(SoftmaxLayer)
+TEST_SUITE(NEON)
+TEST_SUITE(SoftmaxLayer)
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * CNNDataTypes(), shape, dt)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), CNNDataTypes), shape, data_type)
 {
     // Set fixed point position data type allowed
-    int fixed_point_position = (arm_compute::is_data_type_fixed_point(dt)) ? 3 : 0;
+    const int fixed_point_position = is_data_type_fixed_point(data_type) ? 3 : 0;
 
     // Create tensors
-    Tensor src = create_tensor(shape, dt, 1, fixed_point_position);
-    Tensor dst = create_tensor(shape, dt, 1, fixed_point_position);
+    Tensor src = create_tensor<Tensor>(shape, data_type, 1, fixed_point_position);
+    Tensor dst = create_tensor<Tensor>(shape, data_type, 1, fixed_point_position);
 
-    BOOST_TEST(src.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
     NESoftmaxLayer smx_layer;
@@ -126,71 +87,90 @@
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    int               step = 16 / arm_compute::data_size_from_type(dt);
-    const PaddingSize padding(0, required_padding(shape.x(), step), 0, 0);
+    const int         step    = 16 / data_size_from_type(data_type);
+    const PaddingSize padding = PaddingCalculator(shape.x(), step).required_padding();
     validate(src.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_AUTO_TEST_SUITE(Float)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * CNNFloatDataTypes(), shape, dt)
+template <typename T>
+using NESoftmaxLayerFixture = SoftmaxValidationFixture<Tensor, Accessor, NESoftmaxLayer, T>;
+
+TEST_SUITE(Float)
+#ifdef ARM_COMPUTE_ENABLE_FP16
+TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute function
-    Tensor dst = compute_softmax_layer(shape, dt);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_softmax_layer(shape, dt);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance);
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * CNNFloatDataTypes(), shape, dt)
+FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixture<half>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F16)))
 {
-    // Compute function
-    Tensor dst = compute_softmax_layer(shape, dt);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_softmax_layer(shape, dt);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance);
+    validate(Accessor(_target), _reference, tolerance_f16);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
+#endif /* ARM_COMPUTE_ENABLE_FP16 */
 
-BOOST_AUTO_TEST_SUITE(Quantized)
+TEST_SUITE(FP32)
+FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerFixture<float>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixture<float>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_f32);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+template <typename T>
+using NESoftmaxLayerFixedPointFixture = SoftmaxValidationFixedPointFixture<Tensor, Accessor, NESoftmaxLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QS8)
 // Testing for fixed point position [1,6) as reciprocal limits the maximum fixed point position to 5
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * CNNFixedPointDataTypes() * boost::unit_test::data::xrange(1, 6),
-                     shape, dt, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerFixedPointFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+                                                                                                                     DataType::QS8)),
+                                                                                                                     framework::dataset::make("FractionalBits", 1, 6)))
 {
-    // Compute function
-    Tensor dst = compute_softmax_layer(shape, dt, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_softmax_layer(shape, dt, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_fixed_point);
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
 }
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * CNNFixedPointDataTypes() * boost::unit_test::data::xrange(1, 6),
-                     shape, dt, fixed_point_position)
+FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixedPointFixture<int8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+                                                                                                                   DataType::QS8)),
+                                                                                                                   framework::dataset::make("FractionalBits", 1, 6)))
 {
-    // Compute function
-    Tensor dst = compute_softmax_layer(shape, dt, fixed_point_position);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_softmax_layer(shape, dt, fixed_point_position);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst, tolerance_fixed_point);
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
 }
-BOOST_AUTO_TEST_SUITE_END()
+TEST_SUITE_END()
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE(QS16)
+// Testing for fixed point position [1,14) as reciprocal limits the maximum fixed point position to 14
+FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerFixedPointFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(),
+                                                                                                                      framework::dataset::make("DataType",
+                                                                                                                              DataType::QS16)),
+                                                                                                                      framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
+}
+FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixedPointFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(),
+                                                                                                                    framework::dataset::make("DataType",
+                                                                                                                            DataType::QS16)),
+                                                                                                                    framework::dataset::make("FractionalBits", 1, 14)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference, tolerance_fixed_point);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/TableLookup.cpp b/tests/validation/NEON/TableLookup.cpp
new file mode 100644
index 0000000..8a9e05a
--- /dev/null
+++ b/tests/validation/NEON/TableLookup.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/functions/NETableLookup.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "arm_compute/runtime/TensorAllocator.h"
+
+#include "tests/NEON/Accessor.h"
+#include "tests/NEON/LutAccessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/framework/datasets/Datasets.h"
+
+#include "tests/validation/Helpers.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/TableLookupFixture.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(TableLookup)
+
+template <typename T>
+using NETableLookupFixture = TableLookupValidationFixture<Tensor, Accessor, NETableLookup, LutAccessor<T>, Lut, T>;
+TEST_SUITE(U8)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(framework::dataset::concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", { DataType::U8, DataType::S16 })),
+               shape, data_type)
+{
+    // Create Lut
+    const int num_elem = (data_type == DataType::U8) ? std::numeric_limits<uint8_t>::max() + 1 : std::numeric_limits<int16_t>::max() - std::numeric_limits<int16_t>::lowest() + 1;
+    Lut       lut(num_elem, data_type);
+
+    switch(data_type)
+    {
+        case DataType::U8:
+            fill_lookuptable(LutAccessor<uint8_t>(lut));
+            break;
+        case DataType::S16:
+            fill_lookuptable(LutAccessor<int16_t>(lut));
+            break;
+        default:
+            ARM_COMPUTE_ERROR("Not supported");
+    }
+
+    // Create tensors
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, data_type);
+
+    // Create and Configure function
+    NETableLookup table_lookup;
+    table_lookup.configure(&src, &lut, &dst);
+
+    // Validate valid region
+    const ValidRegion valid_region = shape_to_valid_region(shape);
+    validate(dst.info()->valid_region(), valid_region);
+
+    // Validate padding
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
+    validate(dst.info()->padding(), padding);
+}
+FIXTURE_DATA_TEST_CASE(RunSmallU8, NETableLookupFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeU8, NETableLookupFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::U8)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE(S16)
+FIXTURE_DATA_TEST_CASE(RunSmallS16, NETableLookupFixture<int16_t>, framework::DatasetMode::PRECOMMIT, combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::S16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+FIXTURE_DATA_TEST_CASE(RunLargeS16, NETableLookupFixture<int16_t>, framework::DatasetMode::NIGHTLY, combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::S16)))
+{
+    // Validate output
+    validate(Accessor(_target), _reference);
+}
+TEST_SUITE_END()
+
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/NEON/Threshold.cpp b/tests/validation/NEON/Threshold.cpp
index 6ac6f3d..e2e96a8 100644
--- a/tests/validation/NEON/Threshold.cpp
+++ b/tests/validation/NEON/Threshold.cpp
@@ -21,134 +21,71 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include "Globals.h"
-#include "NEON/Helper.h"
-#include "NEON/NEAccessor.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "dataset/ThresholdDataset.h"
-#include "validation/Datasets.h"
-#include "validation/Reference.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/Helpers.h"
-#include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/NEON/functions/NEThreshold.h"
-#include "arm_compute/runtime/Tensor.h"
-#include "arm_compute/runtime/TensorAllocator.h"
+#include "tests/NEON/Accessor.h"
+#include "tests/PaddingCalculator.h"
+#include "tests/datasets/ShapeDatasets.h"
+#include "tests/datasets/ThresholdDataset.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Macros.h"
+#include "tests/validation/Validation.h"
+#include "tests/validation/fixtures/ThresholdFixture.h"
 
-#include "boost_wrapper.h"
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::neon;
-using namespace arm_compute::test::validation;
-
-namespace
+namespace arm_compute
 {
-/** Compute Threshold function.
- *
- * @param[in] shape       Shape of the input and output tensors.
- * @param[in] threshold   Threshold. When the threshold type is RANGE, this is used as the lower threshold.
- * @param[in] false_value value to set when the condition is not respected.
- * @param[in] true_value  value to set when the condition is respected.
- * @param[in] type        Thresholding type. Either RANGE or BINARY.
- * @param[in] upper       Upper threshold. Only used when the thresholding type is RANGE.
- *
- * @return Computed output tensor.
- */
-Tensor compute_threshold(const TensorShape &shape, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper)
+namespace test
+{
+namespace validation
+{
+TEST_SUITE(NEON)
+TEST_SUITE(Threshold)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), datasets::MixedThresholdDataset()),
+                                                                   framework::dataset::make("DataType", DataType::U8)),
+               shape, threshold, false_value, true_value, type, upper, data_type)
 {
     // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
+    Tensor src = create_tensor<Tensor>(shape, data_type);
+    Tensor dst = create_tensor<Tensor>(shape, data_type);
+
+    ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
 
     // Create and configure function
     NEThreshold thrsh;
-    thrsh.configure(&src1, &dst, threshold, false_value, true_value, type, upper);
-
-    // Allocate tensors
-    src1.allocator()->allocate();
-    dst.allocator()->allocate();
-
-    BOOST_TEST(!src1.info()->is_resizable());
-    BOOST_TEST(!dst.info()->is_resizable());
-
-    // Fill tensors
-    library->fill_tensor_uniform(NEAccessor(src1), 0);
-
-    // Compute function
-    thrsh.run();
-
-    return dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(NEON)
-BOOST_AUTO_TEST_SUITE(Threshold)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Configuration,
-                     (SmallShapes() + LargeShapes()) * ThresholdDataset(),
-                     shape, thrshConf)
-{
-    // Create tensors
-    Tensor src1 = create_tensor(shape, DataType::U8);
-    Tensor dst  = create_tensor(shape, DataType::U8);
-
-    BOOST_TEST(src1.info()->is_resizable());
-    BOOST_TEST(dst.info()->is_resizable());
-
-    // Create and configure function
-    NEThreshold thrsh;
-    thrsh.configure(&src1, &dst, thrshConf.threshold, thrshConf.false_value, thrshConf.true_value, thrshConf.type, thrshConf.upper);
+    thrsh.configure(&src, &dst, threshold, false_value, true_value, type, upper);
 
     // Validate valid region
     const ValidRegion valid_region = shape_to_valid_region(shape);
-    validate(src1.info()->valid_region(), valid_region);
     validate(dst.info()->valid_region(), valid_region);
 
     // Validate padding
-    const PaddingSize padding(0, required_padding(shape.x(), 16), 0, 0);
-    validate(src1.info()->padding(), padding);
+    const PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+    validate(src.info()->padding(), padding);
     validate(dst.info()->padding(), padding);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall,
-                     SmallShapes() * ThresholdDataset(),
-                     shape, thrshConf)
+template <typename T>
+using ThresholdFixture = ThresholdValidationFixture<Tensor, Accessor, NEThreshold, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, ThresholdFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), datasets::MixedThresholdDataset()),
+                                                                                                       framework::dataset::make("DataType",
+                                                                                                               DataType::U8)))
 {
-    // Compute function
-    Tensor dst = compute_threshold(shape, thrshConf.threshold, thrshConf.false_value, thrshConf.true_value, thrshConf.type, thrshConf.upper);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_threshold(shape, thrshConf.threshold, thrshConf.false_value, thrshConf.true_value, thrshConf.type, thrshConf.upper);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge,
-                     LargeShapes() * ThresholdDataset(),
-                     shape, thrshConf)
+FIXTURE_DATA_TEST_CASE(RunLarge, ThresholdFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), datasets::MixedThresholdDataset()),
+                                                                                                     framework::dataset::make("DataType",
+                                                                                                             DataType::U8)))
 {
-    // Compute function
-    Tensor dst = compute_threshold(shape, thrshConf.threshold, thrshConf.false_value, thrshConf.true_value, thrshConf.type, thrshConf.upper);
-
-    // Compute reference
-    RawTensor ref_dst = Reference::compute_reference_threshold(shape, thrshConf.threshold, thrshConf.false_value, thrshConf.true_value, thrshConf.type, thrshConf.upper);
-
     // Validate output
-    validate(NEAccessor(dst), ref_dst);
+    validate(Accessor(_target), _reference);
 }
 
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
+TEST_SUITE_END()
+TEST_SUITE_END()
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/Reference.cpp b/tests/validation/Reference.cpp
deleted file mode 100644
index 263c57b..0000000
--- a/tests/validation/Reference.cpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Reference.h"
-
-#include "Globals.h"
-#include "Helpers.h"
-#include "ReferenceCPP.h"
-#include "TensorLibrary.h"
-#include "validation/Helpers.h"
-
-#include <random>
-
-using namespace arm_compute::test;
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-RawTensor Reference::compute_reference_integral_image(const TensorShape &shape)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, DataType::U8);
-    RawTensor ref_dst = library->get(shape, DataType::U32);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src, 0);
-
-    // Compute reference
-    ReferenceCPP::integral_image(ref_src, ref_dst);
-
-    return ref_dst;
-}
-RawTensor Reference::compute_reference_absolute_difference(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, dt_in0);
-    RawTensor ref_src2 = library->get(shape, dt_in1);
-    RawTensor ref_dst  = library->get(shape, dt_out);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::absolute_difference(ref_src1, ref_src2, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_accumulate(const TensorShape &shape)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, DataType::U8);
-    RawTensor ref_dst = library->get(shape, DataType::S16);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src, 0);
-    library->fill_tensor_uniform(ref_dst, 1);
-
-    // Compute reference
-    ReferenceCPP::accumulate(ref_src, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_accumulate_squared(const TensorShape &shape, uint32_t shift)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, DataType::U8);
-    RawTensor ref_dst = library->get(shape, DataType::S16);
-
-    // Fill reference
-    // ref_dst tensor filled with non-negative values
-    library->fill_tensor_uniform(ref_src, 0);
-    library->fill_tensor_uniform(ref_dst, 1, static_cast<int16_t>(0), std::numeric_limits<int16_t>::max());
-
-    // Compute reference
-    ReferenceCPP::accumulate_squared(ref_src, ref_dst, shift);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_accumulate_weighted(const TensorShape &shape, float alpha)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, DataType::U8);
-    RawTensor ref_dst = library->get(shape, DataType::U8);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src, 0);
-    library->fill_tensor_uniform(ref_dst, 1);
-
-    // Compute reference
-    ReferenceCPP::accumulate_weighted(ref_src, ref_dst, alpha);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_arithmetic_addition(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy convert_policy)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, dt_in0);
-    RawTensor ref_src2 = library->get(shape, dt_in1);
-    RawTensor ref_dst  = library->get(shape, dt_out);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::arithmetic_addition(ref_src1, ref_src2, ref_dst, convert_policy);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_arithmetic_subtraction(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy convert_policy)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, dt_in0);
-    RawTensor ref_src2 = library->get(shape, dt_in1);
-    RawTensor ref_dst  = library->get(shape, dt_out);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::arithmetic_subtraction(ref_src1, ref_src2, ref_dst, convert_policy);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_bitwise_and(const TensorShape &shape)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, DataType::U8);
-    RawTensor ref_src2 = library->get(shape, DataType::U8);
-    RawTensor ref_dst  = library->get(shape, DataType::U8);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::bitwise_and(ref_src1, ref_src2, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_bitwise_or(const TensorShape &shape)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, DataType::U8);
-    RawTensor ref_src2 = library->get(shape, DataType::U8);
-    RawTensor ref_dst  = library->get(shape, DataType::U8);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::bitwise_or(ref_src1, ref_src2, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_bitwise_xor(const TensorShape &shape)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, DataType::U8);
-    RawTensor ref_src2 = library->get(shape, DataType::U8);
-    RawTensor ref_dst  = library->get(shape, DataType::U8);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::bitwise_xor(ref_src1, ref_src2, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_bitwise_not(const TensorShape &shape)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, DataType::U8);
-    RawTensor ref_dst = library->get(shape, DataType::U8);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src, 0);
-
-    // Compute reference
-    ReferenceCPP::bitwise_not(ref_src, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_box3x3(const TensorShape &shape)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, DataType::U8);
-    RawTensor ref_dst = library->get(shape, DataType::U8);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src, 0);
-
-    // Compute reference
-    ReferenceCPP::box3x3(ref_src, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_depth_convert(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift, uint32_t fixed_point_position)
-{
-    RawTensor ref_src = library->get(shape, dt_in, 1, fixed_point_position);
-    RawTensor ref_dst = library->get(shape, dt_out, 1, fixed_point_position);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src, 0);
-
-    // Compute reference
-    ReferenceCPP::depth_convert(ref_src, ref_dst, policy, shift);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_gemm(const TensorShape &src_shape1, const TensorShape &src_shape2, const TensorShape &src_shape3,
-                                            const TensorShape &dst_shape, float alpha, float beta, DataType dt, int fixed_point_position)
-{
-    RawTensor src1 = library->get(src_shape1, dt, 1, fixed_point_position);
-    RawTensor src2 = library->get(src_shape2, dt, 1, fixed_point_position);
-    RawTensor src3 = library->get(src_shape3, dt, 1, fixed_point_position);
-    RawTensor dst  = library->get(dst_shape, dt, 1, fixed_point_position);
-
-    // Fill reference
-    if(dt == DataType::F32)
-    {
-        std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
-        library->fill(src1, distribution, 0);
-        library->fill(src2, distribution, 1);
-        library->fill(src3, distribution, 2);
-    }
-    else
-    {
-        library->fill_tensor_uniform(src1, 0);
-        library->fill_tensor_uniform(src2, 1);
-        library->fill_tensor_uniform(src3, 2);
-    }
-
-    // Compute reference
-    ReferenceCPP::gemm(src1, src2, src3, dst, alpha, beta);
-
-    return dst;
-}
-
-RawTensor Reference::compute_reference_pixel_wise_multiplication(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, float scale, ConvertPolicy convert_policy,
-                                                                 RoundingPolicy rounding_policy)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, dt_in0);
-    RawTensor ref_src2 = library->get(shape, dt_in1);
-    RawTensor ref_dst  = library->get(shape, dt_out);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::pixel_wise_multiplication(ref_src1, ref_src2, ref_dst, scale, convert_policy, rounding_policy);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_fixed_point_pixel_wise_multiplication(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, float scale, int fixed_point_position,
-                                                                             ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, dt_in0, 1, fixed_point_position);
-    RawTensor ref_src2 = library->get(shape, dt_in1, 1, fixed_point_position);
-    RawTensor ref_dst  = library->get(shape, dt_out, 1, fixed_point_position);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-    library->fill_tensor_uniform(ref_src2, 1);
-
-    // Compute reference
-    ReferenceCPP::fixed_point_pixel_wise_multiplication(ref_src1, ref_src2, ref_dst, scale, convert_policy, rounding_policy);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_threshold(const TensorShape &shape, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper)
-{
-    // Create reference
-    RawTensor ref_src1 = library->get(shape, DataType::U8);
-    RawTensor ref_dst  = library->get(shape, DataType::U8);
-
-    // Fill reference
-    library->fill_tensor_uniform(ref_src1, 0);
-
-    // Compute reference
-    ReferenceCPP::threshold(ref_src1, ref_dst, threshold, false_value, true_value, type, upper);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_activation_layer(const TensorShape &shape, DataType dt, ActivationLayerInfo act_info, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, dt, 1, fixed_point_position);
-    RawTensor ref_dst = library->get(shape, dt, 1, fixed_point_position);
-
-    // Fill reference
-    if(dt == DataType::F32)
-    {
-        float min_bound = 0;
-        float max_bound = 0;
-        std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<float>(act_info.activation());
-        std::uniform_real_distribution<> distribution(min_bound, max_bound);
-        library->fill(ref_src, distribution, 0);
-    }
-    else
-    {
-        int min_bound = 0;
-        int max_bound = 0;
-        std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<int8_t>(act_info.activation(), fixed_point_position);
-        std::uniform_int_distribution<> distribution(min_bound, max_bound);
-        library->fill(ref_src, distribution, 0);
-    }
-
-    // Compute reference
-    ReferenceCPP::activation_layer(ref_src, ref_dst, act_info);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_batch_normalization_layer(const TensorShape &shape0, const TensorShape &shape1, DataType dt, float epsilon, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src   = library->get(shape0, dt, 1, fixed_point_position);
-    RawTensor ref_dst   = library->get(shape0, dt, 1, fixed_point_position);
-    RawTensor ref_mean  = library->get(shape1, dt, 1, fixed_point_position);
-    RawTensor ref_var   = library->get(shape1, dt, 1, fixed_point_position);
-    RawTensor ref_beta  = library->get(shape1, dt, 1, fixed_point_position);
-    RawTensor ref_gamma = library->get(shape1, dt, 1, fixed_point_position);
-
-    // Fill tensors with values from -1 to 1.
-    if(dt == DataType::F32)
-    {
-        float min_bound = 0.f;
-        float max_bound = 0.f;
-        std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<float>();
-        std::uniform_real_distribution<> distribution(min_bound, max_bound);
-        std::uniform_real_distribution<> distribution_var(0, max_bound);
-        library->fill(ref_src, distribution, 0);
-        library->fill(ref_mean, distribution, 1);
-        library->fill(ref_var, distribution_var, 0);
-        library->fill(ref_beta, distribution, 3);
-        library->fill(ref_gamma, distribution, 4);
-    }
-    else
-    {
-        int min_bound = 0;
-        int max_bound = 0;
-        std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<int8_t>(fixed_point_position);
-        std::uniform_int_distribution<> distribution(min_bound, max_bound);
-        std::uniform_int_distribution<> distribution_var(0, max_bound);
-        library->fill(ref_src, distribution, 0);
-        library->fill(ref_mean, distribution, 1);
-        library->fill(ref_var, distribution_var, 0);
-        library->fill(ref_beta, distribution, 3);
-        library->fill(ref_gamma, distribution, 4);
-    }
-
-    // Compute reference
-    ReferenceCPP::batch_normalization_layer(ref_src, ref_dst, ref_mean, ref_var, ref_beta, ref_gamma, epsilon, fixed_point_position);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_convolution_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, DataType dt,
-                                                         const PadStrideInfo &conv_info, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src     = library->get(input_shape, dt, 1, fixed_point_position);
-    RawTensor ref_weights = library->get(weights_shape, dt, 1, fixed_point_position);
-    RawTensor ref_bias    = library->get(bias_shape, dt, 1, fixed_point_position);
-    RawTensor ref_dst     = library->get(output_shape, dt, 1, fixed_point_position);
-
-    // Fill reference
-    if(dt == DataType::F32)
-    {
-        std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
-        library->fill(ref_src, distribution, 0);
-        library->fill(ref_weights, distribution, 1);
-        library->fill(ref_bias, distribution, 2);
-    }
-    else
-    {
-        library->fill_tensor_uniform(ref_src, 0);
-        library->fill_tensor_uniform(ref_weights, 1);
-        library->fill_tensor_uniform(ref_bias, 2);
-    }
-
-    // Compute reference
-    ReferenceCPP::convolution_layer(ref_src, ref_weights, ref_bias, ref_dst, conv_info);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_fully_connected_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape,
-                                                             DataType dt, bool transpose_weights, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src  = library->get(input_shape, dt, 1, fixed_point_position);
-    RawTensor ref_bias = library->get(bias_shape, dt, 1, fixed_point_position);
-    RawTensor ref_dst  = library->get(output_shape, dt, 1, fixed_point_position);
-
-    // Swap the first and second dimension of weights' shape if transpose_weights is true
-    TensorShape ws = weights_shape;
-    if(transpose_weights)
-    {
-        const size_t dimx = ws.x();
-        ws.set(0, ws.y());
-        ws.set(1, dimx);
-    }
-
-    RawTensor ref_weights = library->get(ws, dt, 1, fixed_point_position);
-
-    // Fill reference
-    if(dt == DataType::F32)
-    {
-        std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
-        library->fill(ref_src, distribution, 0);
-        library->fill(ref_weights, distribution, 1);
-        library->fill(ref_bias, distribution, 2);
-    }
-    else
-    {
-        library->fill_tensor_uniform(ref_src, 0);
-        library->fill_tensor_uniform(ref_weights, 1);
-        library->fill_tensor_uniform(ref_bias, 2);
-    }
-
-    // Compute reference
-    ReferenceCPP::fully_connected_layer(ref_src, ref_weights, ref_bias, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_normalization_layer(const TensorShape &shape, DataType dt, NormalizationLayerInfo norm_info, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, dt, 1, fixed_point_position);
-    RawTensor ref_dst = library->get(shape, dt, 1, fixed_point_position);
-
-    // Fill reference
-    if(dt == DataType::QS8)
-    {
-        const int8_t one_fixed_point       = 1 << fixed_point_position;
-        const int8_t minus_one_fixed_point = -one_fixed_point;
-        library->fill_tensor_uniform(ref_src, 0, minus_one_fixed_point, one_fixed_point);
-    }
-    else
-    {
-        library->fill_tensor_uniform(ref_src, 0);
-    }
-
-    // Compute reference
-    ReferenceCPP::normalization_layer(ref_src, ref_dst, norm_info);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_pooling_layer(const TensorShape &shape_in, const TensorShape &shape_out, DataType dt, PoolingLayerInfo pool_info, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape_in, dt, 1, fixed_point_position);
-    RawTensor ref_dst = library->get(shape_out, dt, 1, fixed_point_position);
-
-    // Fill reference
-    int min = 0;
-    int max = 0;
-    switch(dt)
-    {
-        case DataType::F32:
-            min = -1;
-            max = 1;
-            break;
-        case DataType::QS8:
-            min = -(1 << fixed_point_position);
-            max = (1 << fixed_point_position);
-            break;
-        default:
-            ARM_COMPUTE_ERROR("DataType not supported.");
-    }
-    std::uniform_real_distribution<> distribution(min, max);
-    library->fill(ref_src, distribution, 0.0);
-
-    // Compute reference
-    ReferenceCPP::pooling_layer(ref_src, ref_dst, pool_info, fixed_point_position);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_softmax_layer(const TensorShape &shape, DataType dt, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, dt, 1, fixed_point_position);
-    RawTensor ref_dst = library->get(shape, dt, 1, fixed_point_position);
-
-    // Fill reference
-    if(arm_compute::is_data_type_float(dt))
-    {
-        std::uniform_real_distribution<> distribution(-10, 10);
-        library->fill(ref_src, distribution, 0);
-    }
-    else
-    {
-        int                             one_fixed = 1 << fixed_point_position;
-        std::uniform_int_distribution<> distribution(-one_fixed, one_fixed);
-        library->fill(ref_src, distribution, 0);
-    }
-
-    // Compute reference
-    ReferenceCPP::softmax_layer(ref_src, ref_dst);
-
-    return ref_dst;
-}
-
-RawTensor Reference::compute_reference_fixed_point_operation(const TensorShape &shape, DataType dt_in, DataType dt_out, FixedPointOp op, int fixed_point_position)
-{
-    // Create reference
-    RawTensor ref_src = library->get(shape, dt_in, 1, fixed_point_position);
-    RawTensor ref_dst = library->get(shape, dt_out, 1, fixed_point_position);
-
-    // Fill reference
-    int min = 0;
-    int max = 0;
-    switch(op)
-    {
-        case(FixedPointOp::INV_SQRT):
-            min = 32;
-            max = 127;
-            break;
-        case(FixedPointOp::LOG):
-            min = (1 << (fixed_point_position - 1));
-            max = 63;
-            break;
-        case(FixedPointOp::EXP):
-            min = 1;
-            max = (1 << (fixed_point_position - 1));
-            break;
-        case(FixedPointOp::RECIPROCAL):
-            min = 15;
-            max = 100;
-            break;
-        default:
-            ARM_COMPUTE_ERROR("Fixed point operation not supported");
-    }
-    std::uniform_int_distribution<> distribution(min, max);
-    library->fill(ref_src, distribution, 0);
-
-    // Compute reference
-    ReferenceCPP::fixed_point_operation(ref_src, ref_dst, op);
-
-    return ref_dst;
-}
-
-} // namespace validation
-} // namespace test
-} // namespace arm_compute
diff --git a/tests/validation/Reference.h b/tests/validation/Reference.h
deleted file mode 100644
index 4e5b462..0000000
--- a/tests/validation/Reference.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_REFERENCE_REFERENCE_H__
-#define __ARM_COMPUTE_TEST_REFERENCE_REFERENCE_H__
-
-#include "RawTensor.h"
-#include "Types.h"
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-/** Interface for reference implementations. */
-class Reference
-{
-public:
-    /** Compute reference integral image.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_integral_image(const TensorShape &shape);
-    /** Compute reference absolute difference.
-     *
-     * @param[in] shape  Shape of the input and output tensors.
-     * @param[in] dt_in0 Data type of first input tensor.
-     * @param[in] dt_in1 Data type of second input tensor.
-     * @param[in] dt_out Data type of the output tensor.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_absolute_difference(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out);
-    /** Compute reference accumulate.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_accumulate(const TensorShape &shape);
-    /** Compute reference accumulate.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     * @param[in] shift A uint32_t value within the range of [0, 15]
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_accumulate_squared(const TensorShape &shape, uint32_t shift);
-    /** Compute reference accumulate.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     * @param[in] alpha A float value within the range of [0, 1]
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_accumulate_weighted(const TensorShape &shape, float alpha);
-    /** Compute reference arithmetic addition.
-     *
-     * @param[in] shape          Shape of the input and output tensors.
-     * @param[in] dt_in0         Data type of first input tensor.
-     * @param[in] dt_in1         Data type of second input tensor.
-     * @param[in] dt_out         Data type of the output tensor.
-     * @param[in] convert_policy Overflow policy of the operation.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_arithmetic_addition(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy convert_policy);
-    /** Compute reference arithmetic subtraction.
-     *
-     * @param[in] shape          Shape of the input and output tensors.
-     * @param[in] dt_in0         Data type of first input tensor.
-     * @param[in] dt_in1         Data type of second input tensor.
-     * @param[in] dt_out         Data type of the output tensor.
-     * @param[in] convert_policy Overflow policy of the operation.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_arithmetic_subtraction(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy convert_policy);
-    /** Compute reference bitwise and.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_bitwise_and(const TensorShape &shape);
-    /** Compute reference bitwise or.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_bitwise_or(const TensorShape &shape);
-    /** Compute reference bitwise xor.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_bitwise_xor(const TensorShape &shape);
-    /** Compute reference bitwise not.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_bitwise_not(const TensorShape &shape);
-    /** Compute reference 3-by-3 box filter.
-     *
-     * @param[in] shape Shape of the input and output tensors.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_box3x3(const TensorShape &shape);
-    /** Compute reference depth convert.
-     *
-     * @param[in] shape                Shape of the input and output tensors.
-     * @param[in] dt_in                Data type of input tensor.
-     * @param[in] dt_out               Data type of the output tensor.
-     * @param[in] policy               Overflow policy of the operation.
-     * @param[in] shift                Value for down/up conversions. Must be 0 <= shift < 8.
-     * @param[in] fixed_point_position Fixed point position.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_depth_convert(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift, uint32_t fixed_point_position);
-    /** Compute matrix multiply function.
-     *
-     * @param[in]  src_shape1           First input tensor shape
-     * @param[in]  src_shape2           Second input tensor shape
-     * @param[in]  src_shape3           Third input tensor shape
-     * @param[out] dst_shape            Output tensor.
-     * @param[in]  alpha                Weight of the matrix product
-     * @param[in]  beta                 Weight of the third matrix
-     * @param[in]  dt                   Tensor's data type
-     * @param[in]  fixed_point_position (Optional) Number of bits for the fractional part of the fixed point numbers
-     *
-     * @return Computed output tensor.
-     */
-    static RawTensor compute_reference_gemm(const TensorShape &src_shape1, const TensorShape &src_shape2, const TensorShape &src_shape3,
-                                            const TensorShape &dst_shape, float alpha, float beta, DataType dt, int fixed_point_position = 0);
-    /** Compute reference pixel-wise multiplication
-     *
-     * @param[in] shape           Shape of the input and output tensors.
-     * @param[in] dt_in0          Data type of first input tensor.
-     * @param[in] dt_in1          Data type of second input tensor.
-     * @param[in] dt_out          Data type of the output tensor.
-     * @param[in] scale           Non-negative scale.
-     * @param[in] convert_policy  Overflow policy of the operation.
-     * @param[in] rounding_policy Rounding policy of the operation.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_pixel_wise_multiplication(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, float scale, ConvertPolicy convert_policy,
-                                                                 RoundingPolicy rounding_policy);
-    /** Compute reference pixel-wise multiplication.
-     *
-     * @param[in] shape                Shape of the input and output tensors.
-     * @param[in] dt_in0               Data type of first input tensor.
-     * @param[in] dt_in1               Data type of second input tensor.
-     * @param[in] dt_out               Data type of the output tensor.
-     * @param[in] scale                Scale to apply after multiplication. Must be positive.
-     * @param[in] fixed_point_position Fixed point position that expresses the number of bits for the fractional part of the number.
-     * @param[in] convert_policy       Overflow policy of the operation.
-     * @param[in] rounding_policy      Rounding policy of the operation.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_fixed_point_pixel_wise_multiplication(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, float scale, int fixed_point_position,
-                                                                             ConvertPolicy convert_policy, RoundingPolicy rounding_policy);
-    /** Compute reference threshold.
-     *
-     * @param[in] shape       Shape of the input and output tensors.
-     * @param[in] threshold   Threshold. When the threshold type is RANGE, this is used as the lower threshold.
-     * @param[in] false_value value to set when the condition is not respected.
-     * @param[in] true_value  value to set when the condition is respected.
-     * @param[in] type        Thresholding type. Either RANGE or BINARY.
-     * @param[in] upper       Upper threshold. Only used when the thresholding type is RANGE.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_threshold(const TensorShape &shape, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper);
-    /** Compute reference activation layer.
-     *
-     * @param[in] shape                Shape of the input and output tensors.
-     * @param[in] dt                   Data type of the tensors.
-     * @param[in] act_info             Activation layer information.
-     * @param[in] fixed_point_position (Optional)Number of bits for the fractional part of fixed point numbers.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_activation_layer(const TensorShape &shape, DataType dt, ActivationLayerInfo act_info, int fixed_point_position = 0);
-    /** Compute reference batch normalization layer.
-     *
-     * @param[in] shape0               Shape of the input and output tensors.
-     * @param[in] shape1               Shape of the vector tensors.
-     * @param[in] dt                   Data type of all input and output tensors.
-     * @param[in] epsilon              Small value to avoid division with zero.
-     * @param[in] fixed_point_position Fixed point position.
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_batch_normalization_layer(const TensorShape &shape0, const TensorShape &shape1, DataType dt, float epsilon, int fixed_point_position = 0);
-    /** Compute reference pixel-wise multiplication
-     *
-     * @param[in] input_shape          Shape for the input tensor
-     * @param[in] weights_shape        Shape for the weights tensor
-     * @param[in] bias_shape           Shape for the bias tensor
-     * @param[in] output_shape         Shape for the output tensor
-     * @param[in] dt                   Data type to use
-     * @param[in] conv_info            Pads and strides information for the convolution layer
-     * @param[in] fixed_point_position Number of bits for the fractional part of the fixed point numbers
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_convolution_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, DataType dt,
-                                                         const PadStrideInfo &conv_info, int fixed_point_position);
-    /** Compute reference for fully connected layer function
-     *
-     * @param[in] input_shape          Shape for the input tensor
-     * @param[in] weights_shape        Shape for the weights tensor
-     * @param[in] bias_shape           Shape for the bias tensor
-     * @param[in] output_shape         Shape for the output tensor
-     * @param[in] dt                   Data type to use
-     * @param[in] transpose_weights    Transpose the weights if true
-     * @param[in] fixed_point_position Number of bits for the fractional part of the fixed point numbers
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_fully_connected_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, DataType dt,
-                                                             bool transpose_weights, int fixed_point_position);
-    /** Compute reference normalization layer.
-     *
-     * @param[in] shape                Shape of the input and output tensors.
-     * @param[in] dt                   Data type of input and output tensors.
-     * @param[in] norm_info            Normalization Layer information.
-     * @param[in] fixed_point_position (Optional) Fixed point position that expresses the number of bits for the fractional part of the number when the tensor's data type is QS8 or QS16 (default = 0).
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_normalization_layer(const TensorShape &shape, DataType dt, NormalizationLayerInfo norm_info, int fixed_point_position = 0);
-    /** Compute reference pooling layer.
-      *
-      * @param[in] shape_in             Shape of the input tensor.
-      * @param[in] shape_out            Shape of the output tensor.
-      * @param[in] dt                   Data type of input and output tensors.
-      * @param[in] pool_info            Pooling Layer information.
-      * @param[in] fixed_point_position (Optional) Number of bits for the fractional part of the fixed point numbers.
-      *
-      * @return Computed raw tensor.
-      */
-    static RawTensor compute_reference_pooling_layer(const TensorShape &shape_in, const TensorShape &shape_out, DataType dt, PoolingLayerInfo pool_info, int fixed_point_position = 0);
-    /** Compute reference softmax layer.
-     *
-     * @param[in] shape                Shape of the input and output tensors.
-     * @param[in] dt                   Data type of input and output tensors.
-     * @param[in] fixed_point_position (Optional) Number of bits for the fractional part of the fixed point numbers
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_softmax_layer(const TensorShape &shape, DataType dt, int fixed_point_position = 0);
-    /** Compute reference fixed point operation.
-     *
-     * @param[in] shape                Shape of the input and output tensors.
-     * @param[in] dt_in                Data type of the input tensor.
-     * @param[in] dt_out               Data type of the output tensor.
-     * @param[in] op                   Fixed point operation to perform.
-     * @param[in] fixed_point_position Number of bits for the fractional part of the fixed point numbers
-     *
-     * @return Computed raw tensor.
-     */
-    static RawTensor compute_reference_fixed_point_operation(const TensorShape &shape, DataType dt_in, DataType dt_out, FixedPointOp op, int fixed_point_position);
-
-protected:
-    Reference()  = default;
-    ~Reference() = default;
-};
-} // namespace validation
-} // namespace test
-} // namespace arm_compute
-#endif
diff --git a/tests/validation/ReferenceCPP.cpp b/tests/validation/ReferenceCPP.cpp
deleted file mode 100644
index ddb8483..0000000
--- a/tests/validation/ReferenceCPP.cpp
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "ReferenceCPP.h"
-
-#include "TensorFactory.h"
-#include "TensorOperations.h"
-#include "TensorVisitors.h"
-#include "TypePrinter.h"
-
-#include "arm_compute/core/Coordinates.h"
-#include "arm_compute/core/Error.h"
-#include "arm_compute/core/TensorInfo.h"
-#include "arm_compute/core/TensorShape.h"
-#include "arm_compute/runtime/Tensor.h"
-
-#include "boost_wrapper.h"
-
-#include <functional>
-#include <numeric>
-#include <vector>
-
-using namespace arm_compute::test::validation::tensor_visitors;
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-// Absolute difference
-void ReferenceCPP::absolute_difference(const RawTensor &src1, const RawTensor &src2, RawTensor &dst)
-{
-    const TensorVariant s1 = TensorFactory::get_tensor(src1);
-    const TensorVariant s2 = TensorFactory::get_tensor(src2);
-    TensorVariant       d  = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(absolute_difference_visitor(), s1, s2, d);
-}
-// Integral image
-void ReferenceCPP::integral_image(const RawTensor &src, RawTensor &dst)
-{
-    ARM_COMPUTE_ERROR_ON(src.data_type() != DataType::U8 || dst.data_type() != DataType::U32);
-    const Tensor<uint8_t> s(src.shape(), src.data_type(), src.fixed_point_position(), reinterpret_cast<const uint8_t *>(src.data()));
-    Tensor<uint32_t>      d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint32_t *>(dst.data()));
-    tensor_operations::integral_image(s, d);
-}
-// Accumulate
-void ReferenceCPP::accumulate(const RawTensor &src, RawTensor &dst)
-{
-    ARM_COMPUTE_ERROR_ON(src.data_type() != DataType::U8 || dst.data_type() != DataType::S16);
-    const Tensor<uint8_t> s(src.shape(), src.data_type(), src.fixed_point_position(), reinterpret_cast<const uint8_t *>(src.data()));
-    Tensor<int16_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<int16_t *>(dst.data()));
-    tensor_operations::accumulate(s, d);
-}
-
-// Accumulate squared
-void ReferenceCPP::accumulate_squared(const RawTensor &src, RawTensor &dst, uint32_t shift)
-{
-    ARM_COMPUTE_ERROR_ON(src.data_type() != DataType::U8 || dst.data_type() != DataType::S16);
-    const Tensor<uint8_t> s(src.shape(), src.data_type(), src.fixed_point_position(), reinterpret_cast<const uint8_t *>(src.data()));
-    Tensor<int16_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<int16_t *>(dst.data()));
-    tensor_operations::accumulate_squared(s, d, shift);
-}
-
-// Accumulate weighted
-void ReferenceCPP::accumulate_weighted(const RawTensor &src, RawTensor &dst, float alpha)
-{
-    ARM_COMPUTE_ERROR_ON(src.data_type() != DataType::U8 || dst.data_type() != DataType::U8);
-    const Tensor<uint8_t> s(src.shape(), src.data_type(), src.fixed_point_position(), reinterpret_cast<const uint8_t *>(src.data()));
-    Tensor<uint8_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint8_t *>(dst.data()));
-    tensor_operations::accumulate_weighted(s, d, alpha);
-}
-
-// Arithmetic addition
-void ReferenceCPP::arithmetic_addition(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, ConvertPolicy convert_policy)
-{
-    const TensorVariant s1 = TensorFactory::get_tensor(src1);
-    const TensorVariant s2 = TensorFactory::get_tensor(src2);
-    TensorVariant       d  = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(arithmetic_addition_visitor(convert_policy), s1, s2, d);
-}
-
-// Arithmetic subtraction
-void ReferenceCPP::arithmetic_subtraction(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, ConvertPolicy convert_policy)
-{
-    const TensorVariant s1 = TensorFactory::get_tensor(src1);
-    const TensorVariant s2 = TensorFactory::get_tensor(src2);
-    TensorVariant       d  = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(arithmetic_subtraction_visitor(convert_policy), s1, s2, d);
-}
-
-// Bitwise and
-void ReferenceCPP::bitwise_and(const RawTensor &src1, const RawTensor &src2, RawTensor &dst)
-{
-    ARM_COMPUTE_ERROR_ON(src1.data_type() != DataType::U8 || src2.data_type() != DataType::U8 || dst.data_type() != DataType::U8);
-    const Tensor<uint8_t> s1(src1.shape(), src1.data_type(), src1.fixed_point_position(), reinterpret_cast<const uint8_t *>(src1.data()));
-    const Tensor<uint8_t> s2(src2.shape(), src2.data_type(), src2.fixed_point_position(), reinterpret_cast<const uint8_t *>(src2.data()));
-    Tensor<uint8_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint8_t *>(dst.data()));
-    tensor_operations::bitwise_and(s1, s2, d);
-}
-
-// Bitwise or
-void ReferenceCPP::bitwise_or(const RawTensor &src1, const RawTensor &src2, RawTensor &dst)
-{
-    ARM_COMPUTE_ERROR_ON(src1.data_type() != DataType::U8 || src2.data_type() != DataType::U8 || dst.data_type() != DataType::U8);
-    const Tensor<uint8_t> s1(src1.shape(), src1.data_type(), src1.fixed_point_position(), reinterpret_cast<const uint8_t *>(src1.data()));
-    const Tensor<uint8_t> s2(src2.shape(), src2.data_type(), src2.fixed_point_position(), reinterpret_cast<const uint8_t *>(src2.data()));
-    Tensor<uint8_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint8_t *>(dst.data()));
-    tensor_operations::bitwise_or(s1, s2, d);
-}
-
-// Bitwise xor
-void ReferenceCPP::bitwise_xor(const RawTensor &src1, const RawTensor &src2, RawTensor &dst)
-{
-    ARM_COMPUTE_ERROR_ON(src1.data_type() != DataType::U8 || src2.data_type() != DataType::U8 || dst.data_type() != DataType::U8);
-    const Tensor<uint8_t> s1(src1.shape(), src1.data_type(), src1.fixed_point_position(), reinterpret_cast<const uint8_t *>(src1.data()));
-    const Tensor<uint8_t> s2(src2.shape(), src2.data_type(), src2.fixed_point_position(), reinterpret_cast<const uint8_t *>(src2.data()));
-    Tensor<uint8_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint8_t *>(dst.data()));
-    tensor_operations::bitwise_xor(s1, s2, d);
-}
-
-// Bitwise not
-void ReferenceCPP::bitwise_not(const RawTensor &src, RawTensor &dst)
-{
-    ARM_COMPUTE_ERROR_ON(src.data_type() != DataType::U8 || dst.data_type() != DataType::U8);
-    const Tensor<uint8_t> s(src.shape(), src.data_type(), src.fixed_point_position(), reinterpret_cast<const uint8_t *>(src.data()));
-    Tensor<uint8_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint8_t *>(dst.data()));
-    tensor_operations::bitwise_not(s, d);
-}
-
-// 3-by-3 box filter
-void ReferenceCPP::box3x3(const RawTensor &src, RawTensor &dst)
-{
-    ARM_COMPUTE_ERROR_ON(src.data_type() != DataType::U8 || dst.data_type() != DataType::U8);
-    const Tensor<uint8_t> s(src.shape(), src.data_type(), src.fixed_point_position(), reinterpret_cast<const uint8_t *>(src.data()));
-    Tensor<uint8_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint8_t *>(dst.data()));
-    tensor_operations::box3x3(s, d);
-}
-
-// Depth conversion
-void ReferenceCPP::depth_convert(const RawTensor &src, RawTensor &dst, ConvertPolicy policy, uint32_t shift)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::depth_convert_visitor(policy, shift), s, d);
-}
-
-// GEMM
-void ReferenceCPP::gemm(const RawTensor &src1, const RawTensor &src2, const RawTensor &src3,
-                        RawTensor &dst, float alpha, float beta)
-{
-    const TensorVariant s1 = TensorFactory::get_tensor(src1);
-    const TensorVariant s2 = TensorFactory::get_tensor(src2);
-    const TensorVariant s3 = TensorFactory::get_tensor(src3);
-    TensorVariant       d  = TensorFactory::get_tensor(dst);
-
-    boost::apply_visitor(tensor_visitors::gemm_visitor(s1, s2, s3, alpha, beta), d);
-}
-
-// Pixel-wise multiplication
-void ReferenceCPP::pixel_wise_multiplication(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-{
-    const TensorVariant s1 = TensorFactory::get_tensor(src1);
-    const TensorVariant s2 = TensorFactory::get_tensor(src2);
-    TensorVariant       d  = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(pixel_wise_multiplication_visitor(scale, convert_policy, rounding_policy), s1, s2, d);
-}
-
-// Fixed-point Pixel-wise multiplication
-void ReferenceCPP::fixed_point_pixel_wise_multiplication(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-{
-    const TensorVariant s1 = TensorFactory::get_tensor(src1);
-    const TensorVariant s2 = TensorFactory::get_tensor(src2);
-    TensorVariant       d  = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::fixed_point_pixel_wise_multiplication_visitor(s1, s2, scale, convert_policy, rounding_policy), d);
-}
-
-// Threshold
-void ReferenceCPP::threshold(const RawTensor &src, RawTensor &dst, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper)
-{
-    ARM_COMPUTE_ERROR_ON(src.data_type() != DataType::U8 || dst.data_type() != DataType::U8);
-    const Tensor<uint8_t> s(src.shape(), src.data_type(), src.fixed_point_position(), reinterpret_cast<const uint8_t *>(src.data()));
-    Tensor<uint8_t>       d(dst.shape(), dst.data_type(), dst.fixed_point_position(), reinterpret_cast<uint8_t *>(dst.data()));
-    threshold_operation(s, d, threshold, false_value, true_value, type, upper);
-}
-
-// Activation layer
-void ReferenceCPP::activation_layer(const RawTensor &input, RawTensor &output, ActivationLayerInfo act_info)
-{
-    const TensorVariant s = TensorFactory::get_tensor(input);
-    TensorVariant       d = TensorFactory::get_tensor(output);
-    boost::apply_visitor(tensor_visitors::activation_layer_visitor(s, act_info), d);
-}
-
-// Batch Normalization Layer
-void ReferenceCPP::batch_normalization_layer(const RawTensor &src, RawTensor &dst, const RawTensor &mean, const RawTensor &var, const RawTensor &beta, const RawTensor &gamma, float epsilon,
-                                             int fixed_point_position)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    const TensorVariant m = TensorFactory::get_tensor(mean);
-    const TensorVariant v = TensorFactory::get_tensor(var);
-    const TensorVariant b = TensorFactory::get_tensor(beta);
-    const TensorVariant g = TensorFactory::get_tensor(gamma);
-    boost::apply_visitor(tensor_visitors::batch_normalization_layer_visitor(s, m, v, b, g, epsilon, fixed_point_position), d);
-}
-
-// Convolution Layer
-void ReferenceCPP::convolution_layer(const RawTensor &src, const RawTensor &weights, const RawTensor &bias, RawTensor &dst, const PadStrideInfo &conv_info)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    const TensorVariant w = TensorFactory::get_tensor(weights);
-    const TensorVariant b = TensorFactory::get_tensor(bias);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::convolution_layer_visitor(s, w, b, conv_info), d);
-}
-
-// Fully connected layer
-void ReferenceCPP::fully_connected_layer(const RawTensor &src, const RawTensor &weights, const RawTensor &bias, RawTensor &dst)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    const TensorVariant w = TensorFactory::get_tensor(weights);
-    const TensorVariant b = TensorFactory::get_tensor(bias);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::fully_connected_layer_visitor(s, w, b), d);
-}
-
-// Normalization Layer
-void ReferenceCPP::normalization_layer(const RawTensor &src, RawTensor &dst, NormalizationLayerInfo norm_info)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::normalization_layer_visitor(s, norm_info), d);
-}
-
-// Pooling Layer
-void ReferenceCPP::pooling_layer(const RawTensor &src, RawTensor &dst, PoolingLayerInfo pool_info, int fixed_point_position)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::pooling_layer_visitor(s, pool_info, fixed_point_position), d);
-}
-
-// Softmax Layer
-void ReferenceCPP::softmax_layer(const RawTensor &src, RawTensor &dst)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::softmax_layer_visitor(s), d);
-}
-
-// Fixed point operation
-void ReferenceCPP::fixed_point_operation(const RawTensor &src, RawTensor &dst, FixedPointOp op)
-{
-    const TensorVariant s = TensorFactory::get_tensor(src);
-    TensorVariant       d = TensorFactory::get_tensor(dst);
-    boost::apply_visitor(tensor_visitors::fixed_point_operation_visitor(s, op), d);
-}
-
-} // namespace validation
-} // namespace test
-} // namespace arm_compute
diff --git a/tests/validation/ReferenceCPP.h b/tests/validation/ReferenceCPP.h
deleted file mode 100644
index be5a733..0000000
--- a/tests/validation/ReferenceCPP.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_REFERENCE_REFERENCE_CPP_H__
-#define __ARM_COMPUTE_TEST_REFERENCE_REFERENCE_CPP_H__
-
-#include "Reference.h"
-
-#include "RawTensor.h"
-
-#include <ostream>
-
-namespace arm_compute
-{
-class Tensor;
-
-namespace test
-{
-namespace validation
-{
-/** C++ reference implementation. */
-class ReferenceCPP final : public Reference
-{
-public:
-    /** Function to compute the integral image of a tensor.
-     *
-     * @param[in]  src Input tensor.
-     * @param[out] dst Result tensor.
-     */
-    static void integral_image(const RawTensor &src, RawTensor &dst);
-    /** Function to compute the absolute difference between two tensors.
-     *
-     * @param[in]  src1 First tensor.
-     * @param[in]  src2 Second tensor.
-     * @param[out] dst  Result tensor.
-     */
-    static void absolute_difference(const RawTensor &src1, const RawTensor &src2, RawTensor &dst);
-    /** Function to accumulate an input tensor into an output tensor.
-     *
-     * @param[in]      src Input tensor.
-     * @param[in, out] dst Result tensor.
-     */
-    static void accumulate(const RawTensor &src, RawTensor &dst);
-    /** Function to accumulate a squared value from an input tensor to an output tensor.
-     *
-     * @param[in]      src   Input tensor.
-     * @param[in, out] dst   Result tensor.
-     * @param[in]      shift A uint32_t value within the range of [0, 15]
-     */
-    static void accumulate_squared(const RawTensor &src, RawTensor &dst, uint32_t shift);
-    /** Function to accumulate a weighted value from an input tensor to an output tensor.
-     *
-     * @param[in]      src   Input tensor.
-     * @param[in, out] dst   Result tensor.
-     * @param[in]      alpha A float value within the range of [0, 1]
-     */
-    static void accumulate_weighted(const RawTensor &src, RawTensor &dst, float alpha);
-    /** Arithmetic addition of @p src1 and @p src2
-     *
-     * @param[in]  src1           First tensor.
-     * @param[in]  src2           Second tensor.
-     * @param[out] dst            Result tensor.
-     * @param[in]  convert_policy Overflow policy.
-     */
-    static void arithmetic_addition(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, ConvertPolicy convert_policy);
-    /** Arithmetic subtraction of @p src2 from @p src1
-     *
-     * @param[in]  src1           First tensor.
-     * @param[in]  src2           Second tensor.
-     * @param[out] dst            Result tensor.
-     * @param[in]  convert_policy Overflow policy.
-     */
-    static void arithmetic_subtraction(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, ConvertPolicy convert_policy);
-    /** Function to compute the bitwise and between two tensors.
-     *
-     * @param[in]  src1 First tensor.
-     * @param[in]  src2 Second tensor.
-     * @param[out] dst  Result tensor.
-     */
-    static void bitwise_and(const RawTensor &src1, const RawTensor &src2, RawTensor &dst);
-    /** Function to compute the bitwise or between two tensors.
-     *
-     * @param[in]  src1 First tensor.
-     * @param[in]  src2 Second tensor.
-     * @param[out] dst  Result tensor.
-     */
-    static void bitwise_or(const RawTensor &src1, const RawTensor &src2, RawTensor &dst);
-    /** Function to compute the bitwise xor between two tensors.
-     *
-     * @param[in]  src1 First tensor.
-     * @param[in]  src2 Second tensor.
-     * @param[out] dst  Result tensor.
-     */
-    static void bitwise_xor(const RawTensor &src1, const RawTensor &src2, RawTensor &dst);
-    /** Function to compute the bitwise not of a tensor.
-     *
-     * @param[in]  src Input tensor.
-     * @param[out] dst Result tensor.
-     */
-    static void bitwise_not(const RawTensor &src, RawTensor &dst);
-    /** Function to compute 3-by-3 box filtered result tensor.
-     *
-     * @param[in]  src Input tensor.
-     * @param[out] dst Result tensor.
-     */
-    static void box3x3(const RawTensor &src, RawTensor &dst);
-    /** Depth conversion from @p src to @p dst
-     *
-     * @param[in]  src    First tensor.
-     * @param[out] dst    Result tensor.
-     * @param[in]  policy Overflow policy.
-     * @param[in]  shift  Value for down/up conversions.
-     */
-    static void depth_convert(const RawTensor &src, RawTensor &dst, ConvertPolicy policy, uint32_t shift);
-    /** Compute GEMM function.
-     *
-     * @param[in]  src1  First input tensor
-     * @param[in]  src2  Second input tensor
-     * @param[in]  src3  Third input tensor
-     * @param[out] dst   Output tensr
-     * @param[in]  alpha Weight of the matrix product
-     * @param[in]  beta  Weight of the third matrix
-     */
-    static void gemm(const RawTensor &src1, const RawTensor &src2, const RawTensor &src3,
-                     RawTensor &dst, float alpha, float beta);
-    /** Element-wise multiplication of @p src1, @p src2 and @p scale
-     *
-     * @param[in]  src1            First tensor.
-     * @param[in]  src2            Second tensor.
-     * @param[out] dst             Result tensor.
-     * @param[in]  scale           A non-negative float multiplied to each product.
-     * @param[in]  convert_policy  Overflow policy.
-     * @param[in]  rounding_policy Rounding policy.
-     */
-    static void pixel_wise_multiplication(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy);
-    /** Fixed-point Pixel-wise multiplication of @p src1 by @p src2
-     *
-     * @param[in]  src1            First tensor.
-     * @param[in]  src2            Second tensor.
-     * @param[out] dst             Result tensor.
-     * @param[in]  scale           A non-negative float multiplied to each product.
-     * @param[in]  convert_policy  Overflow policy.
-     * @param[in]  rounding_policy Rounding policy.
-     */
-    static void fixed_point_pixel_wise_multiplication(const RawTensor &src1, const RawTensor &src2, RawTensor &dst, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy);
-    /** Threshold of@p src to @p dst
-     *
-     * @param[in]  src         First tensor.
-     * @param[out] dst         Result tensor.
-     * @param[in]  threshold   Threshold. When the threhold type is RANGE, this is used as the lower threshold.
-     * @param[in]  false_value value to set when the condition is not respected.
-     * @param[in]  true_value  value to set when the condition is respected.
-     * @param[in]  type        Thresholding type. Either RANGE or BINARY.
-     * @param[in]  upper       Upper threshold. Only used when the thresholding type is RANGE.
-     */
-    static void threshold(const RawTensor &src, RawTensor &dst, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper);
-    /** Activation layer of @p src base on information from @p act_info.
-     *
-     * @param[in]  input    Input tensor.
-     * @param[in]  output   Second tensor.
-     * @param[out] act_info Activation layer information.
-     */
-    static void activation_layer(const RawTensor &input, RawTensor &output, ActivationLayerInfo act_info);
-    /** Batch Normalization of @p src based on the information from @p norm_info.
-     *
-     * @param[in]  src                  Input tensor.
-     * @param[out] dst                  Result tensor.
-     * @param[out] mean                 Mean vector tensor.
-     * @param[out] var                  Var vector tensor.
-     * @param[out] beta                 Beta vector tensor.
-     * @param[out] gamma                Gamma vector tensor.
-     * @param[in]  epsilon              Small value to avoid division with zero.
-     * @param[in]  fixed_point_position Fixed point position.
-     */
-    static void batch_normalization_layer(const RawTensor &src, RawTensor &dst, const RawTensor &mean, const RawTensor &var, const RawTensor &beta, const RawTensor &gamma, float epsilon,
-                                          int fixed_point_position = 0);
-    /** Convolution layer function
-     *
-     * @param[in]  src       Input tensor.
-     * @param[in]  weights   Weights tensor.
-     * @param[in]  bias      Bias tensor.
-     * @param[out] dst       Result tensor.
-     * @param[in]  conv_info Pads and strides information for the convolution layer.
-     */
-    static void convolution_layer(const RawTensor &src, const RawTensor &weights, const RawTensor &bias, RawTensor &dst, const PadStrideInfo &conv_info);
-    /** Fully connected layer function
-     *
-     * @param[in]  src     Input tensor
-     * @param[in]  weights Weights tensor.
-     * @param[in]  bias    Bias tensor.
-     * @param[out] dst     Result tensor.
-     */
-    static void fully_connected_layer(const RawTensor &src, const RawTensor &weights, const RawTensor &bias, RawTensor &dst);
-    /** Normalization of @p src based on the information from @p norm_info.
-     *
-     * @param[in]  src       Input tensor.
-     * @param[out] dst       Result tensor.
-     * @param[in]  norm_info Normalization Layer information.
-     */
-    static void normalization_layer(const RawTensor &src, RawTensor &dst, NormalizationLayerInfo norm_info);
-    /** Pooling layer of @p src based on the information from @p norm_info.
-     *
-     * @param[in]  src                  Input tensor.
-     * @param[out] dst                  Result tensor.
-     * @param[in]  pool_info            Pooling Layer information.
-     * @param[in]  fixed_point_position Fixed point position. (Optional)
-     */
-    static void pooling_layer(const RawTensor &src, RawTensor &dst, PoolingLayerInfo pool_info, int fixed_point_position = 0);
-    /** Softmax Layer of @p src.
-     *
-     * @param[in]  src Input tensor.
-     * @param[out] dst Result tensor.
-     */
-    static void softmax_layer(const RawTensor &src, RawTensor &dst);
-    /** Fixed point operations of @p src
-     *
-     * @param[in]  src Input tensor.
-     * @param[out] dst Result tensor.
-     * @param[in]  op  Fixed point operation to perform.
-     */
-    static void fixed_point_operation(const RawTensor &src, RawTensor &dst, FixedPointOp op);
-
-private:
-    ReferenceCPP()  = delete;
-    ~ReferenceCPP() = delete;
-};
-} // namespace validation
-} // namespace test
-} // namespace arm_compute
-#endif
diff --git a/tests/validation/Tensor.h b/tests/validation/Tensor.h
deleted file mode 100644
index 81066b40a..0000000
--- a/tests/validation/Tensor.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_TENSOR_H__
-#define __ARM_COMPUTE_TEST_TENSOR_H__
-
-#include "arm_compute/core/TensorShape.h"
-#include "arm_compute/core/Types.h"
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-template <typename T>
-class Tensor
-{
-public:
-    Tensor()
-        : _shape(), _dt(DataType::UNKNOWN), _fixed_point_position(0), _ptr(nullptr), _ptr_const(nullptr) {};
-
-    Tensor(TensorShape shape, DataType dt, int fixed_point_position, T *ptr)
-        : _shape(shape), _dt(dt), _fixed_point_position(fixed_point_position), _ptr(ptr), _ptr_const(nullptr) {};
-
-    Tensor(TensorShape shape, DataType dt, int fixed_point_position, const T *ptr)
-        : _shape(shape), _dt(dt), _fixed_point_position(fixed_point_position), _ptr(nullptr), _ptr_const(ptr) {};
-
-    Tensor(const Tensor &tensor) = delete;
-    Tensor &operator=(const Tensor &) = delete;
-    Tensor(Tensor &&)                 = default;
-    Tensor &operator=(Tensor &&) = default;
-
-    ~Tensor() = default;
-
-    T &operator[](size_t offset)
-    {
-        return _ptr[offset];
-    }
-
-    const T &operator[](size_t offset) const
-    {
-        return _ptr_const[offset];
-    }
-
-    int num_elements() const
-    {
-        return std::accumulate(_shape.cbegin(), _shape.cend(), 1, std::multiplies<int>());
-    }
-
-    TensorShape shape() const
-    {
-        return _shape;
-    }
-
-    DataType data_type() const
-    {
-        return _dt;
-    }
-
-    int fixed_point_position() const
-    {
-        return _fixed_point_position;
-    }
-
-    const T *data() const
-    {
-        return (_ptr != nullptr) ? _ptr : _ptr_const;
-    }
-    T *data()
-    {
-        return _ptr;
-    }
-
-    const T *data_const()
-    {
-        return _ptr_const;
-    }
-
-private:
-    TensorShape _shape;
-    DataType    _dt;
-    int         _fixed_point_position;
-    T          *_ptr;
-    const T    *_ptr_const;
-};
-} // namespace validation
-} // test
-} // arm_compute
-
-#endif /* __ARM_COMPUTE_TEST_TENSOR_H__ */
diff --git a/tests/validation/TensorFactory.h b/tests/validation/TensorFactory.h
deleted file mode 100644
index 48f9d67..0000000
--- a/tests/validation/TensorFactory.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_TENSOR_FACTORY_H__
-#define __ARM_COMPUTE_TEST_TENSOR_FACTORY_H__
-
-#include "RawTensor.h"
-#include "Tensor.h"
-#include "arm_compute/core/Error.h"
-
-#include "boost_wrapper.h"
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-using TensorVariant = boost::variant < Tensor<uint8_t>, Tensor<int8_t>,
-      Tensor<uint16_t>, Tensor<int16_t>,
-      Tensor<uint32_t>, Tensor<int32_t>,
-#ifdef ENABLE_FP16
-      Tensor<float16_t>,
-#endif
-      Tensor<float >>;
-
-/** Helper to create a constant type if the passed reference is constant. */
-template <typename R, typename T>
-struct match_const
-{
-    using type = typename std::conditional<std::is_const<typename std::remove_reference<R>::type>::value, const T, T>::type;
-};
-
-class TensorFactory
-{
-public:
-    template <typename R>
-    static TensorVariant get_tensor(R &&raw)
-    {
-        TensorVariant v;
-        DataType      dt                   = raw.data_type();
-        int           fixed_point_position = raw.fixed_point_position();
-        auto          shape                = raw.shape();
-        auto          data                 = raw.data();
-
-        switch(dt)
-        {
-            case DataType::U8:
-                using value_type_u8 = typename match_const<R, uint8_t>::type;
-                v                   = Tensor<uint8_t>(shape, dt, fixed_point_position, reinterpret_cast<value_type_u8 *>(data));
-                break;
-            case DataType::S8:
-            case DataType::QS8:
-                using value_type_s8 = typename match_const<R, int8_t>::type;
-                v                   = Tensor<int8_t>(shape, dt, fixed_point_position, reinterpret_cast<value_type_s8 *>(data));
-                break;
-            case DataType::U16:
-                using value_type_u16 = typename match_const<R, uint16_t>::type;
-                v                    = Tensor<uint16_t>(shape, dt, fixed_point_position, reinterpret_cast<value_type_u16 *>(data));
-                break;
-            case DataType::S16:
-                using value_type_s16 = typename match_const<R, int16_t>::type;
-                v                    = Tensor<int16_t>(shape, dt, fixed_point_position, reinterpret_cast<value_type_s16 *>(data));
-                break;
-            case DataType::U32:
-                using value_type_u32 = typename match_const<R, uint32_t>::type;
-                v                    = Tensor<uint32_t>(shape, dt, fixed_point_position, reinterpret_cast<value_type_u32 *>(data));
-                break;
-            case DataType::S32:
-                using value_type_s32 = typename match_const<R, int32_t>::type;
-                v                    = Tensor<int32_t>(shape, dt, fixed_point_position, reinterpret_cast<value_type_s32 *>(data));
-                break;
-#ifdef ENABLE_FP16
-            case DataType::F16:
-                using value_type_f16 = typename match_const<R, float16_t>::type;
-                v                    = Tensor<float16_t>(raw.shape(), dt, reinterpret_cast<value_type_f16 *>(raw.data()));
-                break;
-#endif
-            case DataType::F32:
-                using value_type_f32 = typename match_const<R, float>::type;
-                v                    = Tensor<float>(shape, dt, fixed_point_position, reinterpret_cast<value_type_f32 *>(data));
-                break;
-            default:
-                ARM_COMPUTE_ERROR("NOT SUPPORTED!");
-        }
-        return v;
-    }
-};
-} // namespace validation
-} // namespace test
-} // namespace arm_compute
-
-#endif /* __ARM_COMPUTE_TEST_TENSOR_FACTORY_H__ */
diff --git a/tests/validation/TensorOperations.h b/tests/validation/TensorOperations.h
deleted file mode 100644
index 5e27e9d..0000000
--- a/tests/validation/TensorOperations.h
+++ /dev/null
@@ -1,1370 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_TENSOR_OPERATIONS_H__
-#define __ARM_COMPUTE_TEST_TENSOR_OPERATIONS_H__
-
-#include "FixedPoint.h"
-#include "Tensor.h"
-#include "Types.h"
-#include "Utils.h"
-
-#include "FixedPoint.h"
-#include "Types.h"
-#include "arm_compute/core/FixedPoint.h"
-#include "arm_compute/core/Types.h"
-#include "tests/validation/FixedPoint.h"
-
-#include <algorithm>
-#include <array>
-#include <cmath>
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-namespace tensor_operations
-{
-namespace
-{
-bool is_valid_pixel(int i, int min, int max)
-{
-    return (i >= min && i < max);
-}
-
-// 3D convolution for floating point type
-template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type * = nullptr>
-void convolution3d(const T *in, const T *weights, const T *bias, T *out, int xi, int yi, int width_in, int height_in, int depth_in, int width_weights, int height_weights, int8_t fixed_point_position)
-{
-    const int half_width_weights  = width_weights / 2;
-    const int half_height_weights = height_weights / 2;
-
-    // Reset accumulator
-    T acc = static_cast<T>(0);
-
-    // Compute a 2D convolution for each IFM and accumulate the result
-    for(int ifm = 0; ifm < depth_in; ++ifm)
-    {
-        // Compute the offset for the input slice
-        const int offset_slice_in = xi + yi * width_in + ifm * width_in * height_in;
-
-        // Compute 2D convolution
-        for(int yk = -half_height_weights; yk <= half_height_weights; ++yk)
-        {
-            for(int xk = -half_width_weights; xk <= half_width_weights; ++xk)
-            {
-                // Check if the pixel is out-of-bound
-                if(is_valid_pixel(xi + xk, 0, width_in) && is_valid_pixel(yi + yk, 0, height_in))
-                {
-                    const int idx = xk + half_width_weights;
-                    const int idy = yk + half_height_weights;
-
-                    const T i_value = in[offset_slice_in + xk + yk * width_in];
-                    const T w_value = weights[idx + idy * width_weights + ifm * width_weights * height_weights];
-
-                    acc += i_value * w_value;
-                }
-            }
-        }
-    }
-
-    // Accumulate the bias and store the result
-    *out = acc + (*bias);
-}
-
-// 3D convolution for fixed point type
-template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
-void convolution3d(const T *in, const T *weights, const T *bias, T *out, int xi, int yi, int width_in, int height_in, int depth_in, int width_weights, int height_weights,
-                   int8_t fixed_point_position)
-{
-    const int half_width_weights  = width_weights / 2;
-    const int half_height_weights = height_weights / 2;
-
-    using namespace fixed_point_arithmetic;
-    using promoted_type = typename fixed_point_arithmetic::traits::promote<T>::type;
-
-    // Reset accumulator
-    fixed_point<promoted_type> acc(0, fixed_point_position);
-
-    // Compute a 2D convolution for each IFM and accumulate the result
-    for(int ifm = 0; ifm < depth_in; ++ifm)
-    {
-        // Compute the offset for the input slice
-        const int offset_slice_in = xi + yi * width_in + ifm * width_in * height_in;
-
-        // Compute 2D convolution
-        for(int yk = -half_height_weights; yk <= half_height_weights; ++yk)
-        {
-            for(int xk = -half_width_weights; xk <= half_width_weights; ++xk)
-            {
-                // Check if the pixel is out-of-bound
-                if(is_valid_pixel(xi + xk, 0, width_in) && is_valid_pixel(yi + yk, 0, height_in))
-                {
-                    const int idx = xk + half_width_weights;
-                    const int idy = yk + half_height_weights;
-
-                    const fixed_point<promoted_type> i_value(in[offset_slice_in + xk + yk * width_in], fixed_point_position, true);
-                    const fixed_point<promoted_type> w_value(weights[idx + idy * width_weights + ifm * width_weights * height_weights], fixed_point_position, true);
-                    const fixed_point<promoted_type> iw = i_value * w_value;
-                    acc                                 = iw + acc;
-                }
-            }
-        }
-    }
-
-    // Get the bias
-    const fixed_point<promoted_type> b(*bias, fixed_point_position, true);
-
-    // Accumulate the bias and covert back
-    acc = acc + b;
-    fixed_point<T> res(acc);
-    *out = res.raw();
-}
-
-template <typename T>
-void vector_matrix_multiply(const T *in, const T *weights, const T *bias, T *out, int cols_weights, int rows_weights, uint8_t fixed_point_position)
-{
-    for(int x = 0; x < cols_weights; ++x)
-    {
-        T acc = 0.0f;
-        for(int y = 0; y < rows_weights; ++y)
-        {
-            acc += in[y] * weights[x + y * cols_weights];
-        }
-        out[x] = acc + bias[x];
-    }
-}
-
-template <>
-void vector_matrix_multiply(const int8_t *in, const int8_t *weights, const int8_t *bias, int8_t *out, int cols_weights, int rows_weights, uint8_t fixed_point_position)
-{
-    using namespace fixed_point_arithmetic;
-    using promoted_type = typename fixed_point_arithmetic::traits::promote<int8_t>::type;
-
-    for(int x = 0; x < cols_weights; ++x)
-    {
-        // Reset accumulator
-        fixed_point<promoted_type> acc(0, fixed_point_position);
-
-        for(int y = 0; y < rows_weights; ++y)
-        {
-            const fixed_point<promoted_type> i_value(in[y], fixed_point_position, true);
-            const fixed_point<promoted_type> w_value(weights[x + y * cols_weights], fixed_point_position, true);
-            const fixed_point<promoted_type> iw = i_value * w_value;
-            acc                                 = iw + acc;
-        }
-
-        // Get the bias
-        const fixed_point<int8_t> b(bias[x], fixed_point_position, true);
-
-        // Convert back and accumulate the bias
-        fixed_point<int8_t> res(acc);
-        res = res + b;
-
-        // Store the result
-        out[x] = res.raw();
-    }
-}
-
-/** Apply 2D spatial filter on a single element of @p in at coordinates @p coord
- *
- * - filter sizes have to be odd number
- * - Valid region assumed
- * - Row major order of filter assumed
- * - TO_ZERO rounding policy assumed
- * - SATURATE convert policy assumed
- *
- */
-template <typename T1, typename T2, typename T3>
-void apply_2d_spatial_filter(Coordinates coord, const Tensor<T1> &in, Tensor<T3> &out, const TensorShape &filter_shape, const T2 *filter_itr, float scale)
-{
-    using intermediate_type = typename common_promoted_signed_type<T1, T2, T3>::intermediate_type;
-    intermediate_type val   = 0;
-    int               x     = coord.x();
-    int               y     = coord.y();
-    for(size_t j = y - filter_shape[1] / 2; j <= y + filter_shape[1] / 2; ++j)
-    {
-        for(size_t i = x - filter_shape[0] / 2; i <= x + filter_shape[0] / 2; ++i)
-        {
-            coord.set(0, i);
-            coord.set(1, j);
-            val += static_cast<intermediate_type>(*filter_itr) * static_cast<intermediate_type>(in[coord2index(in.shape(), coord)]);
-            ++filter_itr;
-        }
-    }
-    coord.set(0, x);
-    coord.set(1, y);
-    double rounded_val = cpp11::trunc(val * static_cast<double>(scale));
-    out[coord2index(in.shape(), coord)] = saturate_cast<T3>(rounded_val);
-}
-} // namespace
-
-// Integral Image
-void integral_image(const Tensor<uint8_t> &in, Tensor<uint32_t> &out)
-{
-    // Length of dimensions
-    const size_t width  = in.shape().x();
-    const size_t height = in.shape().y();
-    const size_t depth  = in.shape().z() * in.shape()[3] * in.shape()[4] * in.shape()[5];
-
-    const size_t image_size = width * height;
-
-    for(size_t z = 0; z < depth; ++z)
-    {
-        size_t current_image = z * image_size;
-
-        //First element of each image
-        out[current_image] = in[current_image];
-
-        // First row of each image (add only pixel on the left)
-        for(size_t x = 1; x < width; ++x)
-        {
-            out[current_image + x] = static_cast<uint32_t>(in[current_image + x]) + out[current_image + x - 1];
-        }
-
-        // Subsequent rows
-        for(size_t y = 1; y < height; ++y)
-        {
-            size_t current_row = current_image + (width * y);
-
-            // First element of each row (add only pixel up)
-            out[current_row] = static_cast<uint32_t>(in[current_row]) + out[current_row - width];
-
-            // Following row elements
-            for(size_t x = 1; x < width; ++x)
-            {
-                size_t current_pixel = current_row + x;
-
-                // out = in + up(out) + left(out) - up_left(out)
-                out[current_pixel] = static_cast<uint32_t>(in[current_pixel]) + out[current_pixel - 1]
-                                     + out[current_pixel - width] - out[current_pixel - width - 1];
-            }
-        }
-    }
-}
-
-// Absolute difference
-template <typename T1, typename T2, typename T3>
-void absolute_difference(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out)
-{
-    using intermediate_type = typename common_promoted_signed_type<T1, T2, T3>::intermediate_type;
-
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        intermediate_type val = std::abs(static_cast<intermediate_type>(in1[i]) - static_cast<intermediate_type>(in2[i]));
-        out[i]                = saturate_cast<T3>(val);
-    }
-}
-
-// Accumulate
-template <typename T1, typename T2>
-void accumulate(const Tensor<T1> &in, Tensor<T2> &out)
-{
-    using intermediate_type = typename common_promoted_signed_type<T1, T2>::intermediate_type;
-
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        intermediate_type val = static_cast<intermediate_type>(out[i]) + static_cast<intermediate_type>(in[i]);
-        out[i]                = saturate_cast<T2>(val);
-    }
-}
-
-// Accumulate squared
-template <typename T1, typename T2>
-void accumulate_squared(const Tensor<T1> &in, Tensor<T2> &out, uint32_t shift)
-{
-    if(shift > 15)
-    {
-        ARM_COMPUTE_ERROR("Shift in accumulate_squared must be within the range [0, 15]");
-    }
-    using intermediate_type = typename common_promoted_signed_type<T1, T2>::intermediate_type;
-    intermediate_type denom = 1 << shift;
-
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        intermediate_type val = static_cast<intermediate_type>(out[i]) + (static_cast<intermediate_type>(in[i]) * static_cast<intermediate_type>(in[i]) / denom);
-        out[i]                = saturate_cast<T2>(val);
-    }
-}
-
-// Accumulate weighted
-template <typename T>
-void accumulate_weighted(const Tensor<T> &in, Tensor<T> &out, float alpha)
-{
-    if(alpha < 0.f || alpha > 1.f)
-    {
-        ARM_COMPUTE_ERROR("Weight (alpha) specified in accumulate_weighted must be within the range [0, 1]");
-    }
-    using intermediate_type = typename common_promoted_signed_type<T>::intermediate_type;
-
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        double val = (1. - static_cast<double>(alpha)) * static_cast<intermediate_type>(out[i]) + static_cast<double>(alpha) * static_cast<intermediate_type>(in[i]);
-        out[i]     = static_cast<T>(val);
-    }
-}
-
-// Arithmetic addition
-template <typename T1, typename T2, typename T3>
-void arithmetic_addition(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out, ConvertPolicy convert_policy)
-{
-    using intermediate_type = typename common_promoted_signed_type<T1, T2, T3>::intermediate_type;
-
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        intermediate_type val = static_cast<intermediate_type>(in1[i]) + static_cast<intermediate_type>(in2[i]);
-        out[i]                = (convert_policy == ConvertPolicy::SATURATE) ? saturate_cast<T3>(val) : static_cast<T3>(val);
-    }
-}
-
-// Arithmetic Subtraction
-template <typename T1, typename T2, typename T3>
-void arithmetic_subtraction(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out, ConvertPolicy convert_policy)
-{
-    using intermediate_type = typename common_promoted_signed_type<T1, T2, T3>::intermediate_type;
-
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        intermediate_type val = static_cast<intermediate_type>(in1[i]) - static_cast<intermediate_type>(in2[i]);
-        out[i]                = (convert_policy == ConvertPolicy::SATURATE) ? saturate_cast<T3>(val) : static_cast<T3>(val);
-    }
-}
-
-// Bitwise and
-template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-void bitwise_and(const Tensor<T> &in1, const Tensor<T> &in2, Tensor<T> &out)
-{
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        out[i] = in1[i] & in2[i];
-    }
-}
-
-// Bitwise or
-template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-void bitwise_or(const Tensor<T> &in1, const Tensor<T> &in2, Tensor<T> &out)
-{
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        out[i] = in1[i] | in2[i];
-    }
-}
-
-// Bitwise xor
-template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-void bitwise_xor(const Tensor<T> &in1, const Tensor<T> &in2, Tensor<T> &out)
-{
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        out[i] = in1[i] ^ in2[i];
-    }
-}
-
-// Bitwise not
-template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-void bitwise_not(const Tensor<T> &in, Tensor<T> &out)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out[i] = ~in[i];
-    }
-}
-
-// 3-by-3 box filter
-template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-void box3x3(const Tensor<T> &in, Tensor<T> &out)
-{
-    const std::array<T, 9> filter{ { 1, 1, 1, 1, 1, 1, 1, 1, 1 } };
-    float             scale        = 1.f / static_cast<float>(filter.size());
-    const ValidRegion valid_region = shape_to_valid_region_undefined_border(in.shape(), BorderSize(1));
-    for(int element_idx = 0; element_idx < in.num_elements(); ++element_idx)
-    {
-        const Coordinates id = index2coord(in.shape(), element_idx);
-        if(is_in_valid_region(valid_region, id))
-        {
-            apply_2d_spatial_filter(id, in, out, TensorShape(3U, 3U), filter.data(), scale);
-        }
-    }
-}
-
-// Depth conversion
-template <typename T1, typename T2>
-void depth_convert(const Tensor<T1> &in, Tensor<T2> &out, ConvertPolicy policy, uint32_t shift)
-{
-    ARM_COMPUTE_ERROR("The conversion is not supported");
-}
-
-template <>
-void depth_convert<int8_t, float>(const Tensor<int8_t> &in, Tensor<float> &out, ConvertPolicy policy, uint32_t shift)
-{
-    const int8_t fixed_point_position = static_cast<int8_t>(in.fixed_point_position());
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out[i] = static_cast<float>(in[i]) * (1.0f / (1 << fixed_point_position));
-    }
-}
-
-template <>
-void depth_convert<float, int8_t>(const Tensor<float> &in, Tensor<int8_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    const int8_t fixed_point_position = static_cast<int8_t>(in.fixed_point_position());
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        float val = in[i] * (1 << fixed_point_position) + 0.5f;
-        out[i]    = ((policy == ConvertPolicy::SATURATE) ? saturate_cast<int8_t>(val) : static_cast<int8_t>(val));
-    }
-}
-
-template <>
-void depth_convert<uint8_t, uint16_t>(const Tensor<uint8_t> &in, Tensor<uint16_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out[i] = static_cast<uint16_t>(in[i]) << shift;
-    }
-}
-
-template <>
-void depth_convert<uint8_t, int16_t>(const Tensor<uint8_t> &in, Tensor<int16_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out[i] = static_cast<int16_t>(in[i]) << shift;
-    }
-}
-
-template <>
-void depth_convert<uint8_t, int32_t>(const Tensor<uint8_t> &in, Tensor<int32_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out[i] = static_cast<int32_t>(in[i]) << shift;
-    }
-}
-
-template <>
-void depth_convert<uint16_t, uint8_t>(const Tensor<uint16_t> &in, Tensor<uint8_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        uint16_t val = in[i] >> shift;
-        out[i]       = ((policy == ConvertPolicy::SATURATE) ? saturate_cast<uint8_t>(val) : static_cast<uint8_t>(val));
-    }
-}
-
-template <>
-void depth_convert<uint16_t, uint32_t>(const Tensor<uint16_t> &in, Tensor<uint32_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out[i] = static_cast<uint32_t>(in[i]) << shift;
-    }
-}
-
-template <>
-void depth_convert<int16_t, uint8_t>(const Tensor<int16_t> &in, Tensor<uint8_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        int16_t val = in[i] >> shift;
-        out[i]      = ((policy == ConvertPolicy::SATURATE) ? saturate_cast<uint8_t>(val) : static_cast<uint8_t>(val));
-    }
-}
-template <>
-void depth_convert<int16_t, int32_t>(const Tensor<int16_t> &in, Tensor<int32_t> &out, ConvertPolicy policy, uint32_t shift)
-{
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out[i] = static_cast<int32_t>(in[i]) << shift;
-    }
-}
-
-// Matrix multiplication for floating point type
-template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type * = nullptr>
-void gemm(const Tensor<T> &in1, const Tensor<T> &in2, const Tensor<T> &in3, Tensor<T> &out, float alpha, float beta)
-{
-    const int M = out.shape().y();
-    const int N = out.shape().x();
-    const int K = in1.shape().x();
-
-    for(int r = 0; r < M; ++r)
-    {
-        for(int c = 0; c < N; ++c)
-        {
-            T acc = 0.0f;
-
-            for(int k = 0; k < K; ++k)
-            {
-                const T a0 = in1[r * K + k];
-                const T b0 = in2[k * N + c];
-
-                acc += a0 * b0;
-            }
-
-            // Finalize the result: A * B * alpha + C * beta
-            const T c0     = in3[c + r * N];
-            out[c + r * N] = alpha * acc + beta * c0;
-        }
-    }
-}
-
-// Matrix multiplication for fixed point type
-template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
-void gemm(const Tensor<T> &in1, const Tensor<T> &in2, const Tensor<T> &in3, Tensor<T> &out, float alpha, float beta)
-{
-    using namespace fixed_point_arithmetic;
-
-    using promoted_type = typename fixed_point_arithmetic::traits::promote<T>::type;
-
-    const int    M                    = out.shape().y();
-    const int    N                    = out.shape().x();
-    const int    K                    = in1.shape().x();
-    const int8_t fixed_point_position = static_cast<int8_t>(in1.fixed_point_position());
-
-    const fixed_point<T> alpha_q(alpha, fixed_point_position);
-    const fixed_point<T> beta_q(beta, fixed_point_position);
-
-    for(int r = 0; r < M; ++r)
-    {
-        for(int c = 0; c < N; ++c)
-        {
-            fixed_point<promoted_type> acc_q(0, fixed_point_position);
-
-            for(int k = 0; k < K; ++k)
-            {
-                const fixed_point<promoted_type> a0_q(in1[r * K + k], fixed_point_position, true);
-                const fixed_point<promoted_type> b0_q(in2[k * N + c], fixed_point_position, true);
-                const fixed_point<promoted_type> axb_q = a0_q * b0_q;
-
-                acc_q = axb_q + acc_q;
-            }
-
-            // Finalize the result: A * B * alpha + C * beta
-            const fixed_point<T> c0_q(in3[c + r * N], fixed_point_position, true);
-
-            fixed_point<T> res_q(acc_q);
-            res_q = alpha_q * res_q;
-            res_q = (c0_q * beta_q) + res_q;
-
-            // Store the result
-            out[c + r * N] = res_q.raw();
-        }
-    }
-}
-
-// Pixel-wise multiplication
-template <typename T1, typename T2, typename T3>
-void pixel_wise_multiplication(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-{
-    if(scale < 0)
-    {
-        ARM_COMPUTE_ERROR("Scale of pixel-wise multiplication must be non-negative");
-    }
-    using intermediate_type = typename common_promoted_signed_type<T1, T2, T3>::intermediate_type;
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        double val = static_cast<intermediate_type>(in1[i]) * static_cast<intermediate_type>(in2[i]) * static_cast<double>(scale);
-        if(std::is_floating_point<T3>::value)
-        {
-            out[i] = val;
-        }
-        else
-        {
-            double rounded_val = 0;
-            switch(rounding_policy)
-            {
-                case(RoundingPolicy::TO_ZERO):
-                    rounded_val = cpp11::trunc(val);
-                    break;
-                case(RoundingPolicy::TO_NEAREST_UP):
-                    rounded_val = cpp11::round_half_up(val);
-                    break;
-                case(RoundingPolicy::TO_NEAREST_EVEN):
-                    rounded_val = cpp11::round_half_even(val);
-                    break;
-                default:
-                    ARM_COMPUTE_ERROR("Unsupported rounding policy");
-            }
-            out[i] = (convert_policy == ConvertPolicy::SATURATE) ? saturate_cast<T3>(rounded_val) : static_cast<T3>(rounded_val);
-        }
-    }
-}
-
-// Fixed-point Pixel-wise Multiplication
-template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-void fixed_point_pixel_wise_multiplication(const Tensor<T> &in1, const Tensor<T> &in2, Tensor<T> &out, int scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-{
-    using namespace fixed_point_arithmetic;
-
-    const int fixed_point_position = in1.fixed_point_position();
-
-    ARM_COMPUTE_ERROR_ON_MSG(in1.data_type() != in2.data_type() || in1.data_type() != out.data_type(),
-                             "Tensors must all have the same DataType");
-    ARM_COMPUTE_ERROR_ON_MSG(fixed_point_position != in2.fixed_point_position() || fixed_point_position != out.fixed_point_position(),
-                             "Fixed-point position must be the same for both inputs and outputs");
-
-    // Validate fixed_point_position
-    ARM_COMPUTE_ERROR_ON((in1.data_type() == DataType::QS8) && (fixed_point_position == 0 || fixed_point_position > 7));
-    ARM_COMPUTE_ERROR_ON((in1.data_type() == DataType::QS16) && (fixed_point_position == 0 || fixed_point_position > 15));
-
-    fixed_point<T> fp_scale(scale, fixed_point_position);
-    const bool     is_sat     = convert_policy == ConvertPolicy::SATURATE;
-    const bool     do_scaling = scale != 1;
-
-    for(int i = 0; i < in1.num_elements(); ++i)
-    {
-        fixed_point<T> val1(in1[i], fixed_point_position, true);
-        fixed_point<T> val2(in2[i], fixed_point_position, true);
-        fixed_point<T> res = (is_sat) ? val1 * val2 : mul<OverflowPolicy::WRAP>(val1, val2);
-        if(do_scaling)
-        {
-            res = (is_sat) ? res * fp_scale : mul<OverflowPolicy::WRAP>(res, fp_scale);
-        }
-        out[i] = res.raw();
-    }
-}
-
-// Threshold
-template <typename T>
-void threshold(const Tensor<T> &in, Tensor<T> &out, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper)
-{
-    switch(type)
-    {
-        case ThresholdType::BINARY:
-            for(int i = 0; i < in.num_elements(); ++i)
-            {
-                out[i] = ((in[i] > threshold) ? true_value : false_value);
-            }
-            break;
-        case ThresholdType::RANGE:
-            for(int i = 0; i < in.num_elements(); ++i)
-            {
-                if(in[i] > upper)
-                {
-                    out[i] = false_value;
-                }
-                else if(in[i] < threshold)
-                {
-                    out[i] = false_value;
-                }
-                else
-                {
-                    out[i] = true_value;
-                }
-            }
-            break;
-        default:
-            ARM_COMPUTE_ERROR("Thresholding type not recognised");
-            break;
-    }
-}
-
-// Activation Layer for floating point type
-template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type * = nullptr>
-void activation_layer(const Tensor<T> &in, Tensor<T> &out, ActivationLayerInfo act_info)
-{
-    const T a = static_cast<T>(act_info.a());
-    const T b = static_cast<T>(act_info.b());
-
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        T x = in[i];
-        switch(act_info.activation())
-        {
-            case ActivationLayerInfo::ActivationFunction::ABS:
-                out[i] = std::abs(x);
-                break;
-            case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU:
-                out[i] = std::min<T>(a, std::max<T>(0, x));
-                break;
-            case ActivationLayerInfo::ActivationFunction::LINEAR:
-                out[i] = a * x + b;
-                break;
-            case ActivationLayerInfo::ActivationFunction::LOGISTIC:
-                out[i] = static_cast<T>(1) / (static_cast<T>(1) + std::exp(-x));
-                break;
-            case ActivationLayerInfo::ActivationFunction::RELU:
-                out[i] = std::max<T>(0, x);
-                break;
-            case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
-                out[i] = std::log(static_cast<T>(1) + std::exp(x));
-                break;
-            case ActivationLayerInfo::ActivationFunction::SQRT:
-                out[i] = std::sqrt(x);
-                break;
-            case ActivationLayerInfo::ActivationFunction::SQUARE:
-                out[i] = x * x;
-                break;
-            case ActivationLayerInfo::ActivationFunction::TANH:
-                out[i] = a * std::tanh(b * x);
-                break;
-            default:
-                ARM_COMPUTE_ERROR("Activation function not recognised");
-                break;
-        }
-    }
-}
-
-// Activation Layer for fixed point type
-template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
-void activation_layer(const Tensor<T> &in, Tensor<T> &out, ActivationLayerInfo act_info)
-{
-    using namespace fixed_point_arithmetic;
-    int                                     fixed_point_position = in.fixed_point_position();
-    ActivationLayerInfo::ActivationFunction act_func             = act_info.activation();
-    const fixed_point<T>                    a(act_info.a(), fixed_point_position);
-    const fixed_point<T>                    b(act_info.b(), fixed_point_position);
-    const fixed_point<T>                    const_0(0, fixed_point_position);
-    const fixed_point<T>                    const_1(1, fixed_point_position);
-
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        fixed_point<T> x(in[i], fixed_point_position, true);
-        switch(act_func)
-        {
-            case ActivationLayerInfo::ActivationFunction::ABS:
-                out[i] = abs(x).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::BOUNDED_RELU:
-                out[i] = min(a, max(const_0, x)).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::LINEAR:
-                out[i] = add(b, mul(a, x)).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::LOGISTIC:
-                out[i] = (const_1 / (const_1 + exp(-x))).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::RELU:
-                out[i] = max(const_0, x).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
-                out[i] = log(const_1 + exp(x)).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::SQRT:
-                out[i] = (const_1 / inv_sqrt(x)).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::SQUARE:
-                out[i] = mul(x, x).raw();
-                break;
-            case ActivationLayerInfo::ActivationFunction::TANH:
-                out[i] = tanh(x).raw();
-                break;
-            default:
-                ARM_COMPUTE_ERROR("Activation function not recognised");
-                break;
-        }
-    }
-}
-
-// Batch Normalization Layer for fixed point type
-template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
-void batch_normalization_layer(const Tensor<T> &in, Tensor<T> &out, const Tensor<T> &mean, const Tensor<T> &var, const Tensor<T> &beta, const Tensor<T> &gamma, float epsilon, int fixed_point_position)
-{
-    const int cols       = static_cast<int>(in.shape()[0]);
-    const int rows       = static_cast<int>(in.shape()[1]);
-    const int depth      = static_cast<int>(in.shape()[2]);
-    int       upper_dims = in.shape().total_size() / (cols * rows * depth);
-
-    for(int r = 0; r < upper_dims; ++r)
-    {
-        for(int i = 0; i < depth; ++i)
-        {
-            for(int k = 0; k < rows; ++k)
-            {
-                for(int l = 0; l < cols; ++l)
-                {
-                    const int                              pos = l + k * cols + i * rows * cols + r * cols * rows * depth;
-                    fixed_point_arithmetic::fixed_point<T> in_qs8(in[pos], fixed_point_position, true);
-                    fixed_point_arithmetic::fixed_point<T> var_qs8(var[i], fixed_point_position, true);
-                    fixed_point_arithmetic::fixed_point<T> mean_qs8(mean[i], fixed_point_position, true);
-                    fixed_point_arithmetic::fixed_point<T> beta_qs8(beta[i], fixed_point_position, true);
-                    fixed_point_arithmetic::fixed_point<T> gamma_qs8(gamma[i], fixed_point_position, true);
-                    fixed_point_arithmetic::fixed_point<T> epsilon_qs8(epsilon, fixed_point_position);
-
-                    auto denominator = fixed_point_arithmetic::inv_sqrt(var_qs8 + epsilon_qs8);
-                    auto numerator   = in_qs8 - mean_qs8;
-                    auto x_bar       = numerator * denominator;
-                    x_bar            = beta_qs8 + x_bar * gamma_qs8;
-                    out[pos]         = x_bar.raw();
-                }
-            }
-        }
-    }
-}
-
-// Batch Normalization Layer for floating point type
-template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type * = nullptr>
-void batch_normalization_layer(const Tensor<T> &in, Tensor<T> &out, const Tensor<T> &mean, const Tensor<T> &var, const Tensor<T> &beta, const Tensor<T> &gamma, float epsilon, int fixed_point_position)
-{
-    const int cols       = static_cast<int>(in.shape()[0]);
-    const int rows       = static_cast<int>(in.shape()[1]);
-    const int depth      = static_cast<int>(in.shape()[2]);
-    int       upper_dims = in.shape().total_size() / (cols * rows * depth);
-
-    for(int r = 0; r < upper_dims; ++r)
-    {
-        for(int i = 0; i < depth; ++i)
-        {
-            for(int k = 0; k < rows; ++k)
-            {
-                for(int l = 0; l < cols; ++l)
-                {
-                    const int   pos         = l + k * cols + i * rows * cols + r * cols * rows * depth;
-                    const float denominator = sqrt(var[i] + epsilon);
-                    const float numerator   = in[pos] - mean[i];
-                    const float x_bar       = numerator / denominator;
-                    out[pos]                = beta[i] + x_bar * gamma[i];
-                }
-            }
-        }
-    }
-}
-
-// Convolution layer
-template <typename T>
-void convolution_layer(const Tensor<T> &in, const Tensor<T> &weights, const Tensor<T> &bias, Tensor<T> &out, const PadStrideInfo &conv_info)
-{
-    const int width_in       = in.shape().x();
-    const int height_in      = in.shape().y();
-    const int depth_in       = in.shape().z();
-    const int width_out      = out.shape().x();
-    const int height_out     = out.shape().y();
-    const int depth_out      = out.shape().z();
-    const int width_weights  = weights.shape().x();
-    const int height_weights = weights.shape().y();
-    const int depth_weights  = weights.shape().z();
-    const int pad_xi         = std::min(static_cast<int>(conv_info.pad().first), width_weights / 2);
-    const int pad_yi         = std::min(static_cast<int>(conv_info.pad().second), height_weights / 2);
-    const int start_xi       = width_weights / 2 - pad_xi;
-    const int start_yi       = height_weights / 2 - pad_yi;
-    const int end_xi         = width_in - start_xi;
-    const int end_yi         = height_in - start_yi;
-    const int stride_xi      = conv_info.stride().first;
-    const int stride_yi      = conv_info.stride().second;
-    const int num_batches    = in.shape().total_size() / (width_in * height_in * depth_in);
-
-    for(int r = 0; r < num_batches; ++r)
-    {
-        for(int yi = start_yi; yi < end_yi; yi += stride_yi)
-        {
-            for(int xi = start_xi; xi < end_xi; xi += stride_xi)
-            {
-                for(int ofm = 0; ofm < depth_out; ++ofm)
-                {
-                    // Compute input and output offsets
-                    const int offset_in  = r * width_in * height_in * depth_in;
-                    const int xo         = (xi - start_xi) / stride_xi;
-                    const int yo         = (yi - start_yi) / stride_yi;
-                    const int offset_out = xo + yo * width_out + ofm * width_out * height_out + r * width_out * height_out * depth_out;
-
-                    // Compute 3D convolution
-                    convolution3d(in.data() + offset_in,
-                                  weights.data() + ofm * width_weights * height_weights * depth_weights,
-                                  bias.data() + ofm,
-                                  out.data() + offset_out,
-                                  xi, yi,
-                                  width_in, height_in, depth_in,
-                                  width_weights, height_weights,
-                                  static_cast<int8_t>(in.fixed_point_position()));
-                }
-            }
-        }
-    }
-}
-
-// Fully connected layer
-template <typename T>
-void fully_connected_layer(const Tensor<T> &in, const Tensor<T> &weights, const Tensor<T> &bias, Tensor<T> &out)
-{
-    ARM_COMPUTE_ERROR_ON(weights.shape().x() != out.shape().x());
-    ARM_COMPUTE_ERROR_ON(weights.shape().y() != in.shape().x() * in.shape().y() * in.shape().z());
-    const int cols_weights = weights.shape().x();
-    const int rows_weights = weights.shape().y();
-    const int num_batches  = in.shape().total_size() / rows_weights;
-
-    for(int k = 0; k < num_batches; ++k)
-    {
-        vector_matrix_multiply<T>(in.data() + k * rows_weights,
-                                  weights.data(),
-                                  bias.data(),
-                                  out.data() + k * cols_weights,
-                                  cols_weights,
-                                  rows_weights,
-                                  in.fixed_point_position());
-    }
-}
-
-// Normalization Layer for floating point type
-template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type * = nullptr>
-void normalization_layer(const Tensor<T> &in, Tensor<T> &out, NormalizationLayerInfo norm_info)
-{
-    const uint32_t norm_size = norm_info.norm_size();
-    NormType       type      = norm_info.type();
-    float          beta      = norm_info.beta();
-    uint32_t       kappa     = norm_info.kappa();
-
-    const int cols       = static_cast<int>(in.shape()[0]);
-    const int rows       = static_cast<int>(in.shape()[1]);
-    const int depth      = static_cast<int>(in.shape()[2]);
-    int       upper_dims = in.shape().total_size() / (cols * rows);
-
-    float coeff       = norm_info.scale_coeff();
-    int   radius_cols = norm_size / 2;
-    // IN_MAP_1D and CROSS_MAP normalize over a single axis only
-    int radius_rows = (NormType::IN_MAP_2D == type) ? norm_size / 2 : 0;
-
-    if(type == NormType::CROSS_MAP)
-    {
-        // Remove also depth from upper dimensions since it is the axes we want
-        // to use for normalization
-        upper_dims /= depth;
-        for(int r = 0; r < upper_dims; ++r)
-        {
-            for(int i = 0; i < rows; ++i)
-            {
-                for(int k = 0; k < cols; ++k)
-                {
-                    for(int l = 0; l < depth; ++l)
-                    {
-                        float accumulated_scale = 0.f;
-                        for(int j = -radius_cols; j <= radius_cols; ++j)
-                        {
-                            const int z = l + j;
-                            if(z >= 0 && z < depth)
-                            {
-                                const T value = in[k + i * cols + z * rows * cols + r * cols * rows * depth];
-                                accumulated_scale += value * value;
-                            }
-                        }
-                        out[k + i * cols + l * rows * cols + r * cols * rows * depth] = kappa + accumulated_scale * coeff;
-                    }
-                }
-            }
-        }
-    }
-    else
-    {
-        for(int r = 0; r < upper_dims; ++r)
-        {
-            for(int i = 0; i < rows; ++i)
-            {
-                for(int k = 0; k < cols; ++k)
-                {
-                    float accumulated_scale = 0.f;
-                    for(int j = -radius_rows; j <= radius_rows; ++j)
-                    {
-                        const int y = i + j;
-                        for(int l = -radius_cols; l <= radius_cols; ++l)
-                        {
-                            const int x = k + l;
-                            if((x >= 0 && y >= 0) && (x < cols && y < rows))
-                            {
-                                const T value = in[x + y * cols + r * cols * rows];
-                                accumulated_scale += value * value;
-                            }
-                        }
-                    }
-                    out[k + i * cols + r * cols * rows] = kappa + accumulated_scale * coeff;
-                }
-            }
-        }
-    }
-
-    if(beta == 1.f)
-    {
-        for(int i = 0; i < out.num_elements(); ++i)
-        {
-            out[i] = in[i] / out[i];
-        }
-    }
-    else if(beta == 0.5f)
-    {
-        for(int i = 0; i < out.num_elements(); ++i)
-        {
-            out[i] = in[i] / std::sqrt(out[i]);
-        }
-    }
-    else
-    {
-        for(int i = 0; i < out.num_elements(); ++i)
-        {
-            out[i] = in[i] * std::exp(std::log(out[i]) * -beta);
-        }
-    }
-}
-// Normalization Layer for fixed-point types
-template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
-void normalization_layer(const Tensor<T> &in, Tensor<T> &out, NormalizationLayerInfo norm_info)
-{
-    using namespace fixed_point_arithmetic;
-
-    const int fixed_point_position = in.fixed_point_position();
-
-    const uint32_t norm_size = norm_info.norm_size();
-    NormType       type      = norm_info.type();
-    fixed_point<T> beta(norm_info.beta(), fixed_point_position);
-    fixed_point<T> kappa(norm_info.kappa(), fixed_point_position);
-
-    const int cols       = static_cast<int>(in.shape()[0]);
-    const int rows       = static_cast<int>(in.shape()[1]);
-    const int depth      = static_cast<int>(in.shape()[2]);
-    int       upper_dims = in.shape().total_size() / (cols * rows);
-
-    fixed_point<T> coeff(norm_info.scale_coeff(), fixed_point_position);
-    int            radius_cols = norm_size / 2;
-    // IN_MAP_1D and CROSS_MAP normalize over a single axis only
-    int radius_rows = (NormType::IN_MAP_2D == type) ? norm_size / 2 : 0;
-
-    if(type == NormType::CROSS_MAP)
-    {
-        // Remove also depth from upper dimensions since it is the axes we want
-        // to use for normalization
-        upper_dims /= depth;
-        for(int r = 0; r < upper_dims; ++r)
-        {
-            for(int i = 0; i < rows; ++i)
-            {
-                for(int k = 0; k < cols; ++k)
-                {
-                    for(int l = 0; l < depth; ++l)
-                    {
-                        fixed_point<T> accumulated_scale(0.f, fixed_point_position);
-                        for(int j = -radius_cols; j <= radius_cols; ++j)
-                        {
-                            const int z = l + j;
-                            if(z >= 0 && z < depth)
-                            {
-                                const T              value = in[k + i * cols + z * rows * cols + r * cols * rows * depth];
-                                const fixed_point<T> fp_value(value, fixed_point_position, true);
-                                accumulated_scale = add(accumulated_scale, mul(fp_value, fp_value));
-                            }
-                        }
-                        accumulated_scale                                             = add(kappa, mul(accumulated_scale, coeff));
-                        out[k + i * cols + l * rows * cols + r * cols * rows * depth] = accumulated_scale.raw();
-                    }
-                }
-            }
-        }
-    }
-    else
-    {
-        for(int r = 0; r < upper_dims; ++r)
-        {
-            for(int i = 0; i < rows; ++i)
-            {
-                for(int k = 0; k < cols; ++k)
-                {
-                    fixed_point<T> accumulated_scale(0.f, fixed_point_position);
-                    for(int j = -radius_rows; j <= radius_rows; ++j)
-                    {
-                        const int y = i + j;
-                        for(int l = -radius_cols; l <= radius_cols; ++l)
-                        {
-                            const int x = k + l;
-                            if((x >= 0 && y >= 0) && (x < cols && y < rows))
-                            {
-                                const T              value = in[x + y * cols + r * cols * rows];
-                                const fixed_point<T> fp_value(value, fixed_point_position, true);
-                                accumulated_scale = add(accumulated_scale, mul(fp_value, fp_value));
-                            }
-                        }
-                    }
-                    accumulated_scale                   = add(kappa, mul(accumulated_scale, coeff));
-                    out[k + i * cols + r * cols * rows] = accumulated_scale.raw();
-                }
-            }
-        }
-    }
-
-    if(norm_info.beta() == 1.f)
-    {
-        for(int i = 0; i < out.num_elements(); ++i)
-        {
-            fixed_point<T> res = div(fixed_point<T>(in[i], fixed_point_position, true), fixed_point<T>(out[i], fixed_point_position, true));
-            out[i]             = res.raw();
-        }
-    }
-    else
-    {
-        const fixed_point<T> beta(norm_info.beta(), fixed_point_position);
-        for(int i = 0; i < out.num_elements(); ++i)
-        {
-            fixed_point<T> res = pow(fixed_point<T>(out[i], fixed_point_position, true), beta);
-            res                = div(fixed_point<T>(in[i], fixed_point_position, true), res);
-            out[i]             = res.raw();
-        }
-    }
-}
-
-// Pooling layer
-template <typename T>
-void pooling_layer(const Tensor<T> &in, Tensor<T> &out, PoolingLayerInfo pool_info, int fixed_point_position)
-{
-    const int   pool_size     = pool_info.pool_size();
-    PoolingType type          = pool_info.pool_type();
-    int         pool_stride_x = 0;
-    int         pool_stride_y = 0;
-    int         pad_x         = 0;
-    int         pad_y         = 0;
-    std::tie(pool_stride_x, pool_stride_y) = pool_info.pad_stride_info().stride();
-    std::tie(pad_x, pad_y)                 = pool_info.pad_stride_info().pad();
-
-    const int cols_in = static_cast<int>(in.shape()[0]);
-    const int rows_in = static_cast<int>(in.shape()[1]);
-
-    const int cols_out = static_cast<int>(out.shape()[0]);
-    const int rows_out = static_cast<int>(out.shape()[1]);
-
-    int upper_dims = in.shape().total_size() / (cols_in * rows_in);
-
-    int pooled_height = static_cast<int>(ceil(static_cast<float>(rows_in + 2 * pad_x - pool_size) / pool_stride_x)) + 1;
-    int pooled_width  = static_cast<int>(ceil(static_cast<float>(cols_in + 2 * pad_y - pool_size) / pool_stride_y)) + 1;
-
-    if((pooled_height - 1) * pool_stride_x >= rows_in + pad_x)
-    {
-        --pooled_height;
-    }
-    if((pooled_width - 1) * pool_stride_y >= cols_in + pad_y)
-    {
-        --pooled_width;
-    }
-
-    if(type == PoolingType::MAX)
-    {
-        for(int r = 0; r < upper_dims; ++r)
-        {
-            for(int i = 0; i < pooled_height; ++i)
-            {
-                for(int k = 0; k < pooled_width; ++k)
-                {
-                    int hstart = i * pool_stride_x - pad_x;
-                    int wstart = k * pool_stride_y - pad_y;
-                    int hend   = std::min(hstart + pool_size, rows_in);
-                    int wend   = std::min(wstart + pool_size, cols_in);
-                    hstart     = std::max(hstart, 0);
-                    wstart     = std::max(wstart, 0);
-
-                    T max_val = std::numeric_limits<T>::lowest();
-                    for(int y = hstart; y < hend; ++y)
-                    {
-                        for(int x = wstart; x < wend; ++x)
-                        {
-                            T val = in[r * cols_in * rows_in + y * cols_in + x];
-                            if(val > max_val)
-                            {
-                                max_val = val;
-                            }
-                        }
-                    }
-
-                    out[r * rows_out * cols_out + i * pooled_width + k] = max_val;
-                }
-            }
-        }
-    }
-    else // Average pooling
-    {
-        for(int r = 0; r < upper_dims; ++r)
-        {
-            for(int i = 0; i < pooled_height; ++i)
-            {
-                for(int k = 0; k < pooled_width; ++k)
-                {
-                    T avg_val = 0;
-
-                    int hstart = i * pool_stride_x - pad_x;
-                    int wstart = k * pool_stride_y - pad_y;
-                    int hend   = std::min(hstart + pool_size, cols_in + pad_x);
-                    int wend   = std::min(wstart + pool_size, rows_in + pad_y);
-                    int pool   = (hend - hstart) * (wend - wstart);
-                    hstart     = std::max(hstart, 0);
-                    wstart     = std::max(wstart, 0);
-                    hend       = std::min(hend, rows_in);
-                    wend       = std::min(wend, cols_in);
-
-                    if(std::is_floating_point<T>::value)
-                    {
-                        for(int y = hstart; y < hend; ++y)
-                        {
-                            for(int x = wstart; x < wend; ++x)
-                            {
-                                avg_val += in[r * cols_in * rows_in + y * cols_in + x];
-                            }
-                        }
-                        out[r * rows_out * cols_out + i * pooled_width + k] = avg_val / pool;
-                    }
-                    else
-                    {
-                        static std::array<qint8_t, 10> scale_values_q8 =
-                        { { 0x0, 0x0, 0x40, 0x2A, 0x20, 0x19, 0x15, 0x12, 0x10, 0xE } };
-
-                        for(int y = hstart; y < hend; ++y)
-                        {
-                            for(int x = wstart; x < wend; ++x)
-                            {
-                                avg_val = sqadd_qs8(avg_val, in[r * cols_in * rows_in + y * cols_in + x]);
-                            }
-                        }
-                        out[r * rows_out * cols_out + i * pooled_width + k] = sqmul_qs8(avg_val, (scale_values_q8[pool] >> (7 - fixed_point_position)), fixed_point_position);
-                    }
-                }
-            }
-        }
-    }
-}
-
-// Softmax Layer
-template <typename T, typename std::enable_if<std::is_floating_point<T>::value, int>::type * = nullptr>
-void softmax_layer(const Tensor<T> &in, Tensor<T> &out)
-{
-    const int cols       = static_cast<int>(in.shape()[0]);
-    const int upper_dims = in.shape().total_size() / cols;
-    for(int r = 0; r < upper_dims; ++r)
-    {
-        // Find max
-        T max = std::numeric_limits<T>::lowest();
-        for(int c = 0; c < cols; ++c)
-        {
-            const T x = in[r * cols + c];
-            if(x > max)
-            {
-                max = x;
-            }
-        }
-
-        // Regularize
-        T sum = 0;
-        for(int c = 0; c < cols; ++c)
-        {
-            const T res       = exp(in[r * cols + c] - max);
-            out[r * cols + c] = res;
-            sum += res;
-        }
-
-        // Normalize
-        const T norm_val = 1 / sum;
-        for(int c = 0; c < cols; ++c)
-        {
-            out[r * cols + c] *= norm_val;
-        }
-    }
-}
-template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type * = nullptr>
-void softmax_layer(const Tensor<T> &in, Tensor<T> &out)
-{
-    using namespace fixed_point_arithmetic;
-    using promoted_T = typename test::traits::promote<T>::type;
-
-    const int fixed_point_position = in.fixed_point_position();
-    const int cols                 = static_cast<int>(in.shape()[0]);
-    const int upper_dims           = in.shape().total_size() / cols;
-
-    for(int r = 0; r < upper_dims; ++r)
-    {
-        // Find max
-        fixed_point<T> max(std::numeric_limits<T>::lowest(), fixed_point_position, true);
-        for(int c = 0; c < cols; ++c)
-        {
-            const fixed_point<T> x(in[r * cols + c], fixed_point_position, true);
-            if(x > max)
-            {
-                max = x;
-            }
-        }
-
-        // Regularize
-        fixed_point<promoted_T> sum(0, fixed_point_position);
-        for(int c = 0; c < cols; ++c)
-        {
-            const fixed_point<T> x(in[r * cols + c], fixed_point_position, true);
-            fixed_point<T>       res = exp(x - max);
-            out[r * cols + c]        = res.raw();
-            sum                      = add(sum, static_cast<fixed_point<promoted_T>>(res));
-        }
-
-        // Normalize
-        fixed_point<T> sat_sum(sum);
-        for(int c = 0; c < cols; ++c)
-        {
-            const fixed_point<T> x(out[r * cols + c], fixed_point_position, true);
-            out[r * cols + c] = div(x, sat_sum).raw();
-        }
-    }
-}
-
-// Fixed point operations
-template <typename T>
-void fixed_point_operation(const Tensor<T> &in, Tensor<T> &out, FixedPointOp op)
-{
-    int p = in.fixed_point_position();
-    switch(op)
-    {
-        case FixedPointOp::EXP:
-            for(int i = 0; i < in.num_elements(); ++i)
-            {
-                out[i] = fixed_point_arithmetic::exp(fixed_point_arithmetic::fixed_point<T>(in[i], p, true)).raw();
-            }
-            break;
-        case FixedPointOp::LOG:
-            for(int i = 0; i < in.num_elements(); ++i)
-            {
-                out[i] = fixed_point_arithmetic::log(fixed_point_arithmetic::fixed_point<T>(in[i], p, true)).raw();
-            }
-            break;
-        case FixedPointOp::INV_SQRT:
-            for(int i = 0; i < in.num_elements(); ++i)
-            {
-                out[i] = fixed_point_arithmetic::inv_sqrt(fixed_point_arithmetic::fixed_point<T>(in[i], p, true)).raw();
-            }
-            break;
-        case FixedPointOp::RECIPROCAL:
-            for(int i = 0; i < in.num_elements(); ++i)
-            {
-                out[i] = fixed_point_arithmetic::div(fixed_point_arithmetic::fixed_point<T>(1, p), fixed_point_arithmetic::fixed_point<T>(in[i], p, true)).raw();
-            }
-            break;
-        default:
-            ARM_COMPUTE_ERROR("Fixed point operation not supported");
-            break;
-    }
-}
-
-// Tensor print
-template <typename T>
-void print(const Tensor<T> &in, std::ostream &out)
-{
-    out << "\n";
-    for(int i = 0; i < in.num_elements(); ++i)
-    {
-        out << in[i] << " ";
-    }
-    out << "\n";
-}
-} // namespace tensor_operations
-} // namespace validation
-} // namespace test
-} // namespace arm_compute
-
-#endif /* __ARM_COMPUTE_TEST_TENSOR_OPERATIONS_H__ */
diff --git a/tests/validation/TensorVisitors.h b/tests/validation/TensorVisitors.h
deleted file mode 100644
index a274140..0000000
--- a/tests/validation/TensorVisitors.h
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_TENSOR_VISITORS_H__
-#define __ARM_COMPUTE_TEST_TENSOR_VISITORS_H__
-
-#include "Tensor.h"
-#include "TensorOperations.h"
-#include "arm_compute/core/Error.h"
-
-#include "boost_wrapper.h"
-
-#include <ostream>
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-namespace tensor_visitors
-{
-// Absolute Difference visitor
-struct absolute_difference_visitor : public boost::static_visitor<>
-{
-public:
-    template <typename T1, typename T2, typename T3>
-    void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
-    {
-        tensor_operations::absolute_difference(in1, in2, out);
-    }
-};
-// Arithmetic Addition visitor
-struct arithmetic_addition_visitor : public boost::static_visitor<>
-{
-public:
-    explicit arithmetic_addition_visitor(ConvertPolicy convert_policy)
-        : _policy(convert_policy)
-    {
-    }
-
-    template <typename T1, typename T2, typename T3>
-    void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
-    {
-        tensor_operations::arithmetic_addition(in1, in2, out, _policy);
-    }
-
-private:
-    ConvertPolicy _policy;
-};
-// Arithmetic Subtraction visitor
-struct arithmetic_subtraction_visitor : public boost::static_visitor<>
-{
-public:
-    explicit arithmetic_subtraction_visitor(ConvertPolicy convert_policy)
-        : _policy(convert_policy)
-    {
-    }
-
-    template <typename T1, typename T2, typename T3>
-    void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
-    {
-        tensor_operations::arithmetic_subtraction(in1, in2, out, _policy);
-    }
-
-private:
-    ConvertPolicy _policy;
-};
-// Depth Convert visitor
-struct depth_convert_visitor : public boost::static_visitor<>
-{
-public:
-    explicit depth_convert_visitor(ConvertPolicy policy, uint32_t shift)
-        : _policy(policy), _shift(shift)
-    {
-    }
-
-    template <typename T1, typename T2>
-    void operator()(const Tensor<T1> &in, Tensor<T2> &out) const
-    {
-        tensor_operations::depth_convert(in, out, _policy, _shift);
-    }
-
-private:
-    ConvertPolicy _policy;
-    uint32_t      _shift;
-};
-// GEMM visitor
-struct gemm_visitor : public boost::static_visitor<>
-{
-public:
-    explicit gemm_visitor(const TensorVariant &in1, const TensorVariant &in2, const TensorVariant &in3, float alpha, float beta)
-        : _in1(in1), _in2(in2), _in3(in3), _alpha(alpha), _beta(beta)
-    {
-    }
-
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in1 = boost::get<Tensor<T>>(_in1);
-        const Tensor<T> &in2 = boost::get<Tensor<T>>(_in2);
-        const Tensor<T> &in3 = boost::get<Tensor<T>>(_in3);
-        tensor_operations::gemm(in1, in2, in3, out, _alpha, _beta);
-    }
-
-private:
-    const TensorVariant &_in1, &_in2, &_in3;
-    float                _alpha;
-    float                _beta;
-};
-// Pixel-wise Multiplication visitor
-struct pixel_wise_multiplication_visitor : public boost::static_visitor<>
-{
-public:
-    explicit pixel_wise_multiplication_visitor(float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-        : _scale(scale), _convert_policy(convert_policy), _rounding_policy(rounding_policy)
-    {
-    }
-
-    template <typename T1, typename T2, typename T3>
-    void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
-    {
-        tensor_operations::pixel_wise_multiplication(in1, in2, out, _scale, _convert_policy, _rounding_policy);
-    }
-
-private:
-    float          _scale;
-    ConvertPolicy  _convert_policy;
-    RoundingPolicy _rounding_policy;
-};
-// Fixed Point Pixel-wise Multiplication visitor
-struct fixed_point_pixel_wise_multiplication_visitor : public boost::static_visitor<>
-{
-public:
-    explicit fixed_point_pixel_wise_multiplication_visitor(const TensorVariant &in1, const TensorVariant &in2, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
-        : _in1(in1), _in2(in2), _scale(scale), _convert_policy(convert_policy), _rounding_policy(rounding_policy)
-    {
-    }
-
-    template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in1 = boost::get<Tensor<T>>(_in1);
-        const Tensor<T> &in2 = boost::get<Tensor<T>>(_in2);
-        tensor_operations::fixed_point_pixel_wise_multiplication(in1, in2, out, _scale, _convert_policy, _rounding_policy);
-    }
-    template < typename T, typename std::enable_if < !std::is_integral<T>::value, int >::type = 0 >
-    void operator()(Tensor<T> &out) const
-    {
-        ARM_COMPUTE_ERROR("NOT SUPPORTED!");
-    }
-
-private:
-    const TensorVariant &_in1;
-    const TensorVariant &_in2;
-    float                _scale;
-    ConvertPolicy        _convert_policy;
-    RoundingPolicy       _rounding_policy;
-};
-// Threshold operation
-void threshold_operation(const Tensor<uint8_t> &in, Tensor<uint8_t> &out, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper)
-{
-    tensor_operations::threshold(in, out, threshold, false_value, true_value, type, upper);
-}
-// Activation layer visitor
-struct activation_layer_visitor : public boost::static_visitor<>
-{
-public:
-    explicit activation_layer_visitor(const TensorVariant &in, ActivationLayerInfo act_info)
-        : _in(in), _act_info(act_info)
-    {
-    }
-
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const auto &in = boost::get<Tensor<T>>(_in);
-        tensor_operations::activation_layer(in, out, _act_info);
-    }
-
-private:
-    const TensorVariant      &_in;
-    const ActivationLayerInfo _act_info;
-};
-// Batch Normalization Layer visitor
-struct batch_normalization_layer_visitor : public boost::static_visitor<>
-{
-public:
-    explicit batch_normalization_layer_visitor(const TensorVariant &in, const TensorVariant &mean, const TensorVariant &var, const TensorVariant &beta, const TensorVariant &gamma, float epsilon,
-                                               int fixed_point_position = 0)
-        : _in(in), _mean(mean), _var(var), _beta(beta), _gamma(gamma), _epsilon(epsilon), _fixed_point_position(fixed_point_position)
-    {
-    }
-
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in    = boost::get<Tensor<T>>(_in);
-        const Tensor<T> &mean  = boost::get<Tensor<T>>(_mean);
-        const Tensor<T> &var   = boost::get<Tensor<T>>(_var);
-        const Tensor<T> &beta  = boost::get<Tensor<T>>(_beta);
-        const Tensor<T> &gamma = boost::get<Tensor<T>>(_gamma);
-        tensor_operations::batch_normalization_layer(in, out, mean, var, beta, gamma, _epsilon, _fixed_point_position);
-    }
-
-private:
-    const TensorVariant &_in, &_mean, &_var, &_beta, &_gamma;
-    float                _epsilon;
-    int                  _fixed_point_position;
-};
-// Convolution Layer visitor
-struct convolution_layer_visitor : public boost::static_visitor<>
-{
-public:
-    explicit convolution_layer_visitor(const TensorVariant &in, const TensorVariant &weights, const TensorVariant &bias, PadStrideInfo conv_info)
-        : _in(in), _weights(weights), _bias(bias), _conv_info(conv_info)
-    {
-    }
-
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in      = boost::get<Tensor<T>>(_in);
-        const Tensor<T> &weights = boost::get<Tensor<T>>(_weights);
-        const Tensor<T> &bias    = boost::get<Tensor<T>>(_bias);
-        tensor_operations::convolution_layer(in, weights, bias, out, _conv_info);
-    }
-
-private:
-    const TensorVariant &_in;
-    const TensorVariant &_weights;
-    const TensorVariant &_bias;
-    PadStrideInfo        _conv_info;
-};
-
-struct fully_connected_layer_visitor : public boost::static_visitor<>
-{
-public:
-    explicit fully_connected_layer_visitor(const TensorVariant &in, const TensorVariant &weights, const TensorVariant &bias)
-        : _in(in), _weights(weights), _bias(bias)
-    {
-    }
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in      = boost::get<Tensor<T>>(_in);
-        const Tensor<T> &weights = boost::get<Tensor<T>>(_weights);
-        const Tensor<T> &bias    = boost::get<Tensor<T>>(_bias);
-        tensor_operations::fully_connected_layer(in, weights, bias, out);
-    }
-
-private:
-    const TensorVariant &_in;
-    const TensorVariant &_weights;
-    const TensorVariant &_bias;
-};
-
-// Normalization Layer visitor
-struct normalization_layer_visitor : public boost::static_visitor<>
-{
-public:
-    explicit normalization_layer_visitor(const TensorVariant &in, NormalizationLayerInfo norm_info)
-        : _in(in), _norm_info(norm_info)
-    {
-    }
-
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in = boost::get<Tensor<T>>(_in);
-        tensor_operations::normalization_layer(in, out, _norm_info);
-    }
-
-private:
-    const TensorVariant   &_in;
-    NormalizationLayerInfo _norm_info;
-};
-// Pooling layer
-struct pooling_layer_visitor : public boost::static_visitor<>
-{
-public:
-    explicit pooling_layer_visitor(const TensorVariant &in, PoolingLayerInfo pool_info, int fixed_point_position = 0)
-        : _in(in), _pool_info(pool_info), _fixed_point_position(fixed_point_position)
-    {
-    }
-
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in = boost::get<Tensor<T>>(_in);
-        tensor_operations::pooling_layer(in, out, _pool_info, _fixed_point_position);
-    }
-
-private:
-    const TensorVariant &_in;
-    PoolingLayerInfo     _pool_info;
-    int                  _fixed_point_position;
-};
-// Softmax Layer visitor
-struct softmax_layer_visitor : public boost::static_visitor<>
-{
-public:
-    explicit softmax_layer_visitor(const TensorVariant &in)
-        : _in(in)
-    {
-    }
-
-    template <typename T>
-    void operator()(Tensor<T> &out) const
-    {
-        const auto &in = boost::get<Tensor<T>>(_in);
-        tensor_operations::softmax_layer(in, out);
-    }
-
-private:
-    const TensorVariant &_in;
-};
-// Fixed Point operations visitor
-struct fixed_point_operation_visitor : public boost::static_visitor<>
-{
-public:
-    explicit fixed_point_operation_visitor(const TensorVariant &in, FixedPointOp op)
-        : _in(in), _op(op)
-    {
-    }
-
-    template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
-    void operator()(Tensor<T> &out) const
-    {
-        const Tensor<T> &in = boost::get<Tensor<T>>(_in);
-        tensor_operations::fixed_point_operation(in, out, _op);
-    }
-    template < typename T, typename std::enable_if < !std::is_integral<T>::value, int >::type = 0 >
-    void operator()(Tensor<T> &out) const
-    {
-        ARM_COMPUTE_ERROR("NOT SUPPORTED!");
-    }
-
-private:
-    const TensorVariant &_in;
-    FixedPointOp         _op;
-};
-// Print Tensor visitor
-struct print_visitor : public boost::static_visitor<>
-{
-public:
-    explicit print_visitor(std::ostream &out)
-        : _out(out)
-    {
-    }
-
-    template <typename T>
-    void operator()(const Tensor<T> &in) const
-    {
-        tensor_operations::print(in, _out);
-    }
-
-private:
-    std::ostream &_out;
-};
-} // namespace tensor_visitors
-} // namespace validation
-} // namespace test
-} // namespace arm_compute
-
-#endif /* __ARM_COMPUTE_TEST_TENSOR_VISITORS_H__ */
diff --git a/tests/validation/UNIT/FixedPoint.cpp b/tests/validation/UNIT/FixedPoint.cpp
deleted file mode 100644
index 0e53476..0000000
--- a/tests/validation/UNIT/FixedPoint.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "validation/FixedPoint.h"
-
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "validation/Validation.h"
-#include "validation/ValidationUserConfiguration.h"
-
-#include "boost_wrapper.h"
-
-#include <fstream>
-#include <vector>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::validation;
-
-namespace
-{
-std::string func_names[] =
-{
-    "add", "sub", "mul", "exp", "log", "inv_sqrt"
-};
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(UNIT)
-BOOST_AUTO_TEST_SUITE(FixedPoint)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(FixedPointQS8Inputs, boost::unit_test::data::make(func_names) * boost::unit_test::data::xrange(1, 7), func_name, frac_bits)
-{
-    const std::string base_file_name = user_config.path.get() + "/dumps/" + func_name + "_Q8." + cpp11::to_string(frac_bits);
-    std::ifstream     inputs_file{ base_file_name + ".in", std::ios::binary | std::ios::in };
-
-    BOOST_TEST_INFO(base_file_name + ".in");
-    BOOST_TEST_REQUIRE(inputs_file.good());
-
-    float float_val = 0.f;
-
-    // Read first value
-    inputs_file.read(reinterpret_cast<char *>(&float_val), sizeof(float_val));
-
-    while(inputs_file.good())
-    {
-        // Convert to fixed point
-        fixed_point_arithmetic::fixed_point<int8_t> in_val(float_val, frac_bits);
-
-        // Check that the value didn't change
-        BOOST_TEST(static_cast<float>(in_val) == float_val);
-
-        // Read next value
-        inputs_file.read(reinterpret_cast<char *>(&float_val), sizeof(float_val));
-    }
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-// The last input argument specifies the expected number of failures for a
-// given combination of (function name, number of fractional bits) as defined
-// by the first two arguments.
-BOOST_DATA_TEST_CASE(FixedPointQS8Outputs, (boost::unit_test::data::make(func_names) * boost::unit_test::data::xrange(1, 7)) ^ (boost::unit_test::data::make({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 13, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 32, 67 })),
-                     func_name, frac_bits, expected_failures)
-{
-    const std::string base_file_name = user_config.path.get() + "/dumps/" + func_name + "_Q8." + cpp11::to_string(frac_bits);
-    std::ifstream     inputs_file{ base_file_name + ".in", std::ios::binary | std::ios::in };
-    std::ifstream     reference_file{ base_file_name + ".out", std::ios::binary | std::ios::in };
-
-    BOOST_TEST_INFO(base_file_name + ".in");
-    BOOST_TEST_REQUIRE(inputs_file.good());
-    BOOST_TEST_INFO(base_file_name + ".out");
-    BOOST_TEST_REQUIRE(reference_file.good());
-
-    const float step_size = std::pow(2.f, -frac_bits);
-
-    float   float_val      = 0.f;
-    float   ref_val        = 0.f;
-    int64_t num_mismatches = 0;
-
-    // Read first values
-    inputs_file.read(reinterpret_cast<char *>(&float_val), sizeof(float_val));
-    reference_file.read(reinterpret_cast<char *>(&ref_val), sizeof(ref_val));
-
-    while(inputs_file.good() && reference_file.good())
-    {
-        fixed_point_arithmetic::fixed_point<int8_t> in_val(float_val, frac_bits);
-        fixed_point_arithmetic::fixed_point<int8_t> out_val(0.f, frac_bits);
-
-        float tolerance = 0.f;
-
-        if(func_name == "add")
-        {
-            out_val = in_val + in_val;
-        }
-        else if(func_name == "sub")
-        {
-            out_val = in_val - in_val; //NOLINT
-        }
-        else if(func_name == "mul")
-        {
-            tolerance = 1.f * step_size;
-            out_val   = in_val * in_val;
-        }
-        else if(func_name == "exp")
-        {
-            tolerance = 2.f * step_size;
-            out_val   = fixed_point_arithmetic::exp(in_val);
-        }
-        else if(func_name == "log")
-        {
-            tolerance = 4.f * step_size;
-            out_val   = fixed_point_arithmetic::log(in_val);
-        }
-        else if(func_name == "inv_sqrt")
-        {
-            tolerance = 5.f * step_size;
-            out_val   = fixed_point_arithmetic::inv_sqrt(in_val);
-        }
-
-        BOOST_TEST_INFO("input = " << in_val);
-        BOOST_TEST_INFO("output = " << out_val);
-        BOOST_TEST_INFO("reference = " << ref_val);
-        BOOST_TEST_INFO("tolerance = " << tolerance);
-        BOOST_TEST_WARN((std::abs(static_cast<float>(out_val) - ref_val) <= tolerance));
-
-        if(std::abs(static_cast<float>(out_val) - ref_val) > tolerance)
-        {
-            ++num_mismatches;
-        }
-
-        // Read next values
-        inputs_file.read(reinterpret_cast<char *>(&float_val), sizeof(float_val));
-        reference_file.read(reinterpret_cast<char *>(&ref_val), sizeof(ref_val));
-    }
-
-    BOOST_TEST(num_mismatches == expected_failures);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/UNIT/TensorInfo.cpp b/tests/validation/UNIT/TensorInfo.cpp
deleted file mode 100644
index 11ed9f6..0000000
--- a/tests/validation/UNIT/TensorInfo.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "TypePrinter.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/TensorInfo.h"
-#include "arm_compute/core/Types.h"
-
-#include "boost_wrapper.h"
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::validation;
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(UNIT)
-BOOST_AUTO_TEST_SUITE(TensorInfoValidation)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(AutoPadding,
-                     boost::unit_test::data::make({ TensorShape{},
-                                                    TensorShape{ 10U },
-                                                    TensorShape{ 10U, 10U },
-                                                    TensorShape{ 10U, 10U, 10U },
-                                                    TensorShape{ 10U, 10U, 10U, 10U },
-                                                    TensorShape{ 10U, 10U, 10U, 10U, 10U },
-                                                    TensorShape{ 10U, 10U, 10U, 10U, 10U, 10U }
-                                                  })
-                     ^ boost::unit_test::data::make({ PaddingSize{ 0, 0, 0, 0 },
-                                                      PaddingSize{ 0, 36, 0, 4 },
-                                                      PaddingSize{ 4, 36, 4, 4 },
-                                                      PaddingSize{ 4, 36, 4, 4 },
-                                                      PaddingSize{ 4, 36, 4, 4 },
-                                                      PaddingSize{ 4, 36, 4, 4 },
-                                                      PaddingSize{ 4, 36, 4, 4 }
-                                                    })
-                     ^ boost::unit_test::data::make({ Strides{},
-                                                      Strides{ 1U },
-                                                      Strides{ 1U, 50U },
-                                                      Strides{ 1U, 50U, 900U },
-                                                      Strides{ 1U, 50U, 900U, 9000U },
-                                                      Strides{ 1U, 50U, 900U, 9000U, 90000U },
-                                                      Strides{ 1U, 50U, 900U, 9000U, 90000U, 900000U }
-                                                    })
-                     ^ boost::unit_test::data::make(
-{
-    0,
-    4,
-    204,
-    204,
-    204,
-    204,
-    204,
-}),
-shape, auto_padding, strides, offset)
-{
-    TensorInfo info{ shape, Format::U8 };
-
-    BOOST_TEST(!info.has_padding());
-
-    info.auto_padding();
-
-    validate(info.padding(), auto_padding);
-    BOOST_TEST(compare_dimensions(info.strides_in_bytes(), strides));
-    BOOST_TEST(info.offset_first_element_in_bytes() == offset);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/UNIT/TensorShape.cpp b/tests/validation/UNIT/TensorShape.cpp
deleted file mode 100644
index 2d78cd5..0000000
--- a/tests/validation/UNIT/TensorShape.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "TypePrinter.h"
-#include "validation/Validation.h"
-
-#include "arm_compute/core/TensorShape.h"
-
-#include "boost_wrapper.h"
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::validation;
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(UNIT)
-BOOST_AUTO_TEST_SUITE(TensorShapeValidation)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Construction,
-                     boost::unit_test::data::make({ TensorShape{},
-                                                    TensorShape{ 1U },
-                                                    TensorShape{ 2U },
-                                                    TensorShape{ 2U, 3U },
-                                                    TensorShape{ 2U, 3U, 5U },
-                                                    TensorShape{ 2U, 3U, 5U, 7U },
-                                                    TensorShape{ 2U, 3U, 5U, 7U, 11U },
-                                                    TensorShape{ 2U, 3U, 5U, 7U, 11U, 13U }
-                                                  })
-                     ^ boost::unit_test::data::make({ 0, 0, 1, 2, 3, 4, 5, 6 }) ^ boost::unit_test::data::make({ 0, 1, 2, 6, 30, 210, 2310, 30030 }),
-                     shape, num_dimensions, total_size)
-{
-    BOOST_TEST(shape.num_dimensions() == num_dimensions);
-    BOOST_TEST(shape.total_size() == total_size);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(SetEmpty, boost::unit_test::data::make({ 0, 1, 2, 3, 4, 5 }), dimension)
-{
-    TensorShape shape;
-
-    shape.set(dimension, 10);
-
-    BOOST_TEST(shape.num_dimensions() == dimension + 1);
-    BOOST_TEST(shape.total_size() == 10);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/UNIT/Utils.cpp b/tests/validation/UNIT/Utils.cpp
deleted file mode 100644
index 2c3f07b..0000000
--- a/tests/validation/UNIT/Utils.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Utils.h"
-
-#include "TypePrinter.h"
-#include "validation/Validation.h"
-
-#include "boost_wrapper.h"
-
-#include <stdexcept>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::cpp11;
-using namespace arm_compute::test::validation;
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_AUTO_TEST_SUITE(UNIT)
-BOOST_AUTO_TEST_SUITE(Utils)
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RoundHalfUp, boost::unit_test::data::make({ 1.f, 1.2f, 1.5f, 2.5f, 2.9f, -3.f, -3.5f, -3.8f, -4.3f, -4.5f }) ^ boost::unit_test::data::make({ 1.f, 1.f, 2.f, 3.f, 3.f, -3.f, -3.f, -4.f, -4.f, -4.f }),
-                     value, result)
-{
-    BOOST_TEST(cpp11::round_half_up(value) == result);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RoundHalfEven, boost::unit_test::data::make({ 1.f, 1.2f, 1.5f, 2.5f, 2.9f, -3.f, -3.5f, -3.8f, -4.3f, -4.5f }) ^ boost::unit_test::data::make({ 1.f, 1.f, 2.f, 2.f, 3.f, -3.f, -4.f, -4.f, -4.f, -4.f }),
-                     value, result)
-{
-    BOOST_TEST(cpp11::round_half_even(value) == result);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Index2Coord, boost::unit_test::data::make({ TensorShape{ 1U }, TensorShape{ 2U }, TensorShape{ 2U, 3U } }) ^ boost::unit_test::data::make({ 0, 1, 2 }) ^
-                     boost::unit_test::data::make({ Coordinates{ 0 }, Coordinates{ 1 }, Coordinates{ 0, 1 } }), shape, index, ref_coordinate)
-{
-    Coordinates coordinate = index2coord(shape, index);
-
-    BOOST_TEST(compare_dimensions(coordinate, ref_coordinate));
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(Coord2Index, boost::unit_test::data::make({ TensorShape{ 1U }, TensorShape{ 2U }, TensorShape{ 2U, 3U } }) ^ boost::unit_test::data::make({ Coordinates{ 0 }, Coordinates{ 1 }, Coordinates{ 0, 1 } })
-                     ^ boost::unit_test::data::make({ 0, 1, 2 }),
-                     shape, coordinate, ref_index)
-{
-    int index = coord2index(shape, coordinate);
-
-    BOOST_TEST(index == ref_index);
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/VX/DepthConvert.cpp b/tests/validation/VX/DepthConvert.cpp
deleted file mode 100644
index 8b3cc51..0000000
--- a/tests/validation/VX/DepthConvert.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#include "Globals.h"
-#include "TensorLibrary.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-#include "VX/VXAccessor.h"
-#include "dataset/ThresholdDataset.h"
-#include "validation/Datasets.h"
-#include "validation/ReferenceCPP.h"
-#include "validation/VX/VXFixture.h"
-#include "validation/VX/VXHelpers.h"
-#include "validation/Validation.h"
-
-#include "boost_wrapper.h"
-
-#include <VX/vx.h>
-
-#include <random>
-#include <string>
-
-using namespace arm_compute;
-using namespace arm_compute::test;
-using namespace arm_compute::test::vx;
-using namespace arm_compute::test::validation;
-using namespace arm_compute::test::validation::vx;
-
-namespace
-{
-/** Compute VX Depth Covert function.
- *
- * @param[in] context    VX context.
- * @param[in] image_name Image name
- * @param[in] dt_in      Data type of input.
- * @param[in] vxdt_out   VX data type of output.
- * @param[in] policy     Conversion policy.
- * @param[in] shift      Value for down/up conversions. Must be 0 <= shift < 8.
-
- * @note The caller is responsible for releasing the returned vx_image.
- *
- * @return Computed output image.
- *
- */
-vx_image compute_depth_convert(vx_context &context, const std::string &image_name,
-                               Format dt_in, vx_df_image_e vxdt_out, ConvertPolicy policy, uint32_t shift)
-{
-    vx_convert_policy_e vxpolicy = ((policy == ConvertPolicy::SATURATE) ? VX_CONVERT_POLICY_SATURATE : VX_CONVERT_POLICY_WRAP);
-    vx_scalar           vxshift  = vxCreateScalar(context, VX_TYPE_INT32, &shift);
-
-    // Create graph
-    vx_graph graph = vxCreateGraph(context);
-
-    // Create images
-    RawTensor raw = library->get(image_name, dt_in);
-    vx_image  src = vxCreateImage(context, raw.shape()[0], raw.shape()[1], get_vximage_format(dt_in));
-    vx_image  dst = vxCreateImage(context, raw.shape()[0], raw.shape()[1], vxdt_out);
-
-    // Fill images
-    library->fill(VXAccessor(src), image_name, dt_in);
-
-    // Create and configure node
-    vxConvertDepthNode(graph, src, dst, vxpolicy, vxshift);
-
-    // Compute function
-    if(vxVerifyGraph(graph) == VX_SUCCESS)
-    {
-        vxProcessGraph(graph);
-    }
-
-    // Release objects
-    vxReleaseImage(&src);
-    vxReleaseGraph(&graph);
-    vxReleaseScalar(&vxshift);
-
-    return dst;
-}
-
-/** Compute VX reference Depth Covert.
- *
- * @param[in] image_name Image name.
- * @param[in] dt_in      Data type of input.
- * @param[in] dt_out     Data type of output.
- * @param[in] policy     Conversion policy.
- * @param[in] shift      Value for down/up conversions. Must be 0 <= shift < 8. *
- *
- * @return Computed raw tensor.
- */
-RawTensor compute_reference(const std::string &image_name, Format dt_in, Format dt_out, ConvertPolicy policy, uint32_t shift)
-{
-    // Create reference
-    RawTensor ref_src = library->get(image_name, dt_in);
-    RawTensor ref_dst = library->get(ref_src.shape(), dt_out);
-
-    // Fill reference
-    library->fill(ref_src, image_name, dt_in);
-
-    // Compute reference
-    ReferenceCPP::depth_convert(ref_src, ref_dst, policy, shift);
-
-    return ref_dst;
-}
-} // namespace
-
-#ifndef DOXYGEN_SKIP_THIS
-BOOST_FIXTURE_TEST_SUITE(VX, VXFixture)
-BOOST_AUTO_TEST_SUITE(DepthConvert)
-
-BOOST_AUTO_TEST_SUITE(U8_to_U16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP }) * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U8, VX_DF_IMAGE_U16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U8, Format::U16, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U8, VX_DF_IMAGE_U16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U8, Format::U16, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(U8_to_S16)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U8, VX_DF_IMAGE_S16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U8, Format::S16, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-
-BOOST_DATA_TEST_CASE(RunLarge, LargeImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U8, VX_DF_IMAGE_S16, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U8, Format::S16, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(U16_to_U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U16, VX_DF_IMAGE_U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U16, Format::U8, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U16, VX_DF_IMAGE_U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U16, Format::U8, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(U16_to_U32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U16, VX_DF_IMAGE_U32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U16, Format::U32, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::U16, VX_DF_IMAGE_U32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::U16, Format::U32, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(S16_to_U8)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::S16, VX_DF_IMAGE_U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::S16, Format::U8, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::S16, VX_DF_IMAGE_U8, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::S16, Format::U8, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE(S16_to_S32)
-BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
-BOOST_DATA_TEST_CASE(RunSmall, SmallImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::S16, VX_DF_IMAGE_S32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::S16, Format::S32, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-
-BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeImages() * boost::unit_test::data::make({ ConvertPolicy::SATURATE, ConvertPolicy::WRAP })
-                     * boost::unit_test::data::xrange(0, 7, 1),
-                     image_name, policy, shift)
-{
-    // Compute function
-    vx_image dst = compute_depth_convert(context, image_name, Format::S16, VX_DF_IMAGE_S32, policy, shift);
-
-    // Compute reference
-    RawTensor ref_dst = compute_reference(image_name, Format::S16, Format::S32, policy, shift);
-
-    // Validate output
-    validate(VXAccessor(dst), ref_dst);
-
-    vxReleaseImage(&dst);
-}
-BOOST_AUTO_TEST_SUITE_END()
-
-BOOST_AUTO_TEST_SUITE_END()
-BOOST_AUTO_TEST_SUITE_END()
-#endif
diff --git a/tests/validation/Validation.cpp b/tests/validation/Validation.cpp
index 335d264..ebca193 100644
--- a/tests/validation/Validation.cpp
+++ b/tests/validation/Validation.cpp
@@ -23,22 +23,16 @@
  */
 #include "Validation.h"
 
-#include "IAccessor.h"
-#include "RawTensor.h"
-#include "TypePrinter.h"
-#include "Utils.h"
-
 #include "arm_compute/core/Coordinates.h"
 #include "arm_compute/core/Error.h"
-#include "arm_compute/core/FixedPoint.h"
 #include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
 #include "arm_compute/runtime/Tensor.h"
 
 #include <array>
 #include <cmath>
 #include <cstddef>
 #include <cstdint>
-#include <iomanip>
 
 namespace arm_compute
 {
@@ -57,6 +51,11 @@
  */
 double get_double_data(const void *ptr, DataType data_type)
 {
+    if(ptr == nullptr)
+    {
+        ARM_COMPUTE_ERROR("Can't dereference a null pointer!");
+    }
+
     switch(data_type)
     {
         case DataType::U8:
@@ -69,6 +68,8 @@
             return *reinterpret_cast<const uint16_t *>(ptr);
         case DataType::S16:
             return *reinterpret_cast<const int16_t *>(ptr);
+        case DataType::QS16:
+            return *reinterpret_cast<const qint16_t *>(ptr);
         case DataType::U32:
             return *reinterpret_cast<const uint32_t *>(ptr);
         case DataType::S32:
@@ -77,10 +78,8 @@
             return *reinterpret_cast<const uint64_t *>(ptr);
         case DataType::S64:
             return *reinterpret_cast<const int64_t *>(ptr);
-#if ENABLE_FP16
         case DataType::F16:
-            return *reinterpret_cast<const float16_t *>(ptr);
-#endif
+            return *reinterpret_cast<const half *>(ptr);
         case DataType::F32:
             return *reinterpret_cast<const float *>(ptr);
         case DataType::F64:
@@ -102,7 +101,25 @@
     if(border_mode == BorderMode::REPLICATE)
     {
         Coordinates border_id{ id };
-        border_id.set(1, 0);
+
+        if(id.x() < 0)
+        {
+            border_id.set(0, 0);
+        }
+        else if(static_cast<size_t>(id.x()) >= tensor.shape().x())
+        {
+            border_id.set(0, tensor.shape().x() - 1);
+        }
+
+        if(id.y() < 0)
+        {
+            border_id.set(1, 0);
+        }
+        else if(static_cast<size_t>(id.y()) >= tensor.shape().y())
+        {
+            border_id.set(1, tensor.shape().y() - 1);
+        }
+
         border_value = tensor(border_id);
     }
 
@@ -111,124 +128,51 @@
     {
         const size_t channel_offset = channel * channel_size;
         const double target         = get_double_data(ptr + channel_offset, tensor.data_type());
-        const double ref            = get_double_data(static_cast<const uint8_t *>(border_value) + channel_offset, tensor.data_type());
-        const double difference     = target - ref;
+        const double reference      = get_double_data(static_cast<const uint8_t *>(border_value) + channel_offset, tensor.data_type());
 
-        BOOST_TEST_INFO("id = " << id);
-        BOOST_TEST_INFO("channel = " << channel);
-        BOOST_TEST_INFO("reference = " << std::setprecision(5) << ref);
-        BOOST_TEST_INFO("target = " << std::setprecision(5) << target);
-        BOOST_TEST_WARN(difference == 0);
-
-        if(difference != 0.f)
+        if(!compare<AbsoluteTolerance<double>>(target, reference))
         {
+            ARM_COMPUTE_TEST_INFO("id = " << id);
+            ARM_COMPUTE_TEST_INFO("channel = " << channel);
+            ARM_COMPUTE_TEST_INFO("target = " << std::setprecision(5) << target);
+            ARM_COMPUTE_TEST_INFO("reference = " << std::setprecision(5) << reference);
+            ARM_COMPUTE_EXPECT_EQUAL(target, reference, framework::LogLevel::DEBUG);
+
             ++num_mismatches;
         }
 
         ++num_elements;
     }
 }
-
-void check_single_element(const Coordinates &id, const IAccessor &tensor, const RawTensor &reference, float tolerance_value,
-                          uint64_t wrap_range, int min_channels, size_t channel_size, int64_t &num_mismatches, int64_t &num_elements)
-{
-    const auto ptr     = static_cast<const uint8_t *>(tensor(id));
-    const auto ref_ptr = static_cast<const uint8_t *>(reference(id));
-
-    // Iterate over all channels within one element
-    for(int channel = 0; channel < min_channels; ++channel)
-    {
-        const size_t channel_offset = channel * channel_size;
-        const double target         = get_double_data(ptr + channel_offset, reference.data_type());
-        const double ref            = get_double_data(ref_ptr + channel_offset, reference.data_type());
-        const double difference     = target - ref;
-
-        BOOST_TEST_INFO("id = " << id);
-        BOOST_TEST_INFO("channel = " << channel);
-        BOOST_TEST_INFO("reference = " << std::setprecision(5) << ref);
-        BOOST_TEST_INFO("target = " << std::setprecision(5) << target);
-        BOOST_TEST_WARN(difference == 0);
-
-        if(std::abs(difference) > tolerance_value)
-        {
-            // If no special cases for tolerating wrappping cases
-            // or the special case of wrapping exceeds tolerance_value
-            if(wrap_range == 0 || (wrap_range - std::abs(difference)) > tolerance_value)
-            {
-                ++num_mismatches;
-            }
-        }
-        ++num_elements;
-    }
-}
 } // namespace
 
 void validate(const arm_compute::ValidRegion &region, const arm_compute::ValidRegion &reference)
 {
-    BOOST_TEST(region.anchor.num_dimensions() == reference.anchor.num_dimensions());
-    BOOST_TEST(region.shape.num_dimensions() == reference.shape.num_dimensions());
+    ARM_COMPUTE_EXPECT_EQUAL(region.anchor.num_dimensions(), reference.anchor.num_dimensions(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT_EQUAL(region.shape.num_dimensions(), reference.shape.num_dimensions(), framework::LogLevel::ERRORS);
 
     for(unsigned int d = 0; d < region.anchor.num_dimensions(); ++d)
     {
-        BOOST_TEST(region.anchor[d] == reference.anchor[d]);
+        ARM_COMPUTE_EXPECT_EQUAL(region.anchor[d], reference.anchor[d], framework::LogLevel::ERRORS);
     }
 
     for(unsigned int d = 0; d < region.shape.num_dimensions(); ++d)
     {
-        BOOST_TEST(region.shape[d] == reference.shape[d]);
+        ARM_COMPUTE_EXPECT_EQUAL(region.shape[d], reference.shape[d], framework::LogLevel::ERRORS);
     }
 }
 
 void validate(const arm_compute::PaddingSize &padding, const arm_compute::PaddingSize &reference)
 {
-    BOOST_TEST(padding.top == reference.top);
-    BOOST_TEST(padding.right == reference.right);
-    BOOST_TEST(padding.bottom == reference.bottom);
-    BOOST_TEST(padding.left == reference.left);
-}
-
-void validate(const IAccessor &tensor, const RawTensor &reference, float tolerance_value, float tolerance_number, uint64_t wrap_range)
-{
-    // Validate with valid region covering the entire shape
-    validate(tensor, reference, shape_to_valid_region(tensor.shape()), tolerance_value, tolerance_number, wrap_range);
-}
-
-void validate(const IAccessor &tensor, const RawTensor &reference, const ValidRegion &valid_region, float tolerance_value, float tolerance_number, uint64_t wrap_range)
-{
-    int64_t num_mismatches = 0;
-    int64_t num_elements   = 0;
-
-    BOOST_TEST(tensor.element_size() == reference.element_size());
-    BOOST_TEST(tensor.format() == reference.format());
-    BOOST_TEST(tensor.data_type() == reference.data_type());
-    BOOST_TEST(tensor.num_channels() == reference.num_channels());
-    BOOST_TEST(compare_dimensions(tensor.shape(), reference.shape()));
-
-    const int    min_elements = std::min(tensor.num_elements(), reference.num_elements());
-    const int    min_channels = std::min(tensor.num_channels(), reference.num_channels());
-    const size_t channel_size = element_size_from_data_type(reference.data_type());
-
-    // Iterate over all elements within valid region, e.g. U8, S16, RGB888, ...
-    for(int element_idx = 0; element_idx < min_elements; ++element_idx)
-    {
-        const Coordinates id = index2coord(reference.shape(), element_idx);
-        if(is_in_valid_region(valid_region, id))
-        {
-            check_single_element(id, tensor, reference, tolerance_value, wrap_range, min_channels, channel_size, num_mismatches, num_elements);
-        }
-    }
-
-    const int64_t absolute_tolerance_number = tolerance_number * num_elements;
-    const float   percent_mismatches        = static_cast<float>(num_mismatches) / num_elements * 100.f;
-
-    BOOST_TEST(num_mismatches <= absolute_tolerance_number,
-               num_mismatches << " values (" << std::setprecision(2) << percent_mismatches
-               << "%) mismatched (maximum tolerated " << std::setprecision(2) << tolerance_number << "%)");
+    ARM_COMPUTE_EXPECT_EQUAL(padding.top, reference.top, framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT_EQUAL(padding.right, reference.right, framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT_EQUAL(padding.bottom, reference.bottom, framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT_EQUAL(padding.left, reference.left, framework::LogLevel::ERRORS);
 }
 
 void validate(const IAccessor &tensor, const void *reference_value)
 {
-    BOOST_TEST_REQUIRE((reference_value != nullptr));
+    ARM_COMPUTE_ASSERT(reference_value != nullptr);
 
     int64_t      num_mismatches = 0;
     int64_t      num_elements   = 0;
@@ -246,17 +190,16 @@
         {
             const size_t channel_offset = channel * channel_size;
             const double target         = get_double_data(ptr + channel_offset, tensor.data_type());
-            const double ref            = get_double_data(reference_value, tensor.data_type());
-            const double difference     = target - ref;
+            const double reference      = get_double_data(reference_value, tensor.data_type());
 
-            BOOST_TEST_INFO("id = " << id);
-            BOOST_TEST_INFO("channel = " << channel);
-            BOOST_TEST_INFO("reference = " << std::setprecision(5) << ref);
-            BOOST_TEST_INFO("target = " << std::setprecision(5) << target);
-            BOOST_TEST_WARN(difference == 0);
-
-            if(difference != 0.f)
+            if(!compare<AbsoluteTolerance<double>>(target, reference))
             {
+                ARM_COMPUTE_TEST_INFO("id = " << id);
+                ARM_COMPUTE_TEST_INFO("channel = " << channel);
+                ARM_COMPUTE_TEST_INFO("target = " << std::setprecision(5) << target);
+                ARM_COMPUTE_TEST_INFO("reference = " << std::setprecision(5) << reference);
+                ARM_COMPUTE_EXPECT_EQUAL(target, reference, framework::LogLevel::DEBUG);
+
                 ++num_mismatches;
             }
 
@@ -264,10 +207,13 @@
         }
     }
 
-    const float percent_mismatches = static_cast<float>(num_mismatches) / num_elements * 100.f;
+    if(num_elements > 0)
+    {
+        const float percent_mismatches = static_cast<float>(num_mismatches) / num_elements * 100.f;
 
-    BOOST_TEST(num_mismatches == 0,
-               num_mismatches << " values (" << std::setprecision(2) << percent_mismatches << "%) mismatched");
+        ARM_COMPUTE_TEST_INFO(num_mismatches << " values (" << std::fixed << std::setprecision(2) << percent_mismatches << "%) mismatched");
+        ARM_COMPUTE_EXPECT_EQUAL(num_mismatches, 0, framework::LogLevel::ERRORS);
+    }
 }
 
 void validate(const IAccessor &tensor, BorderSize border_size, const BorderMode &border_mode, const void *border_value)
@@ -278,7 +224,7 @@
     }
     else if(border_mode == BorderMode::CONSTANT)
     {
-        BOOST_TEST((border_value != nullptr));
+        ARM_COMPUTE_ASSERT(border_value != nullptr);
     }
 
     int64_t   num_mismatches = 0;
@@ -338,20 +284,37 @@
         }
     }
 
-    const float percent_mismatches = static_cast<float>(num_mismatches) / num_elements * 100.f;
+    if(num_elements > 0)
+    {
+        const float percent_mismatches = static_cast<float>(num_mismatches) / num_elements * 100.f;
 
-    BOOST_TEST(num_mismatches == 0,
-               num_mismatches << " values (" << std::setprecision(2) << percent_mismatches << "%) mismatched");
+        ARM_COMPUTE_TEST_INFO(num_mismatches << " values (" << std::fixed << std::setprecision(2) << percent_mismatches << "%) mismatched");
+        ARM_COMPUTE_EXPECT_EQUAL(num_mismatches, 0, framework::LogLevel::ERRORS);
+    }
 }
 
 void validate(std::vector<unsigned int> classified_labels, std::vector<unsigned int> expected_labels)
 {
-    BOOST_TEST(expected_labels.size() != 0);
-    BOOST_TEST(classified_labels.size() == expected_labels.size());
+    ARM_COMPUTE_EXPECT_EQUAL(classified_labels.size(), expected_labels.size(), framework::LogLevel::ERRORS);
 
-    for(unsigned int i = 0; i < expected_labels.size(); ++i)
+    int64_t   num_mismatches = 0;
+    const int num_elements   = std::min(classified_labels.size(), expected_labels.size());
+
+    for(int i = 0; i < num_elements; ++i)
     {
-        BOOST_TEST(classified_labels[i] == expected_labels[i]);
+        if(classified_labels[i] != expected_labels[i])
+        {
+            ++num_mismatches;
+            ARM_COMPUTE_EXPECT_EQUAL(classified_labels[i], expected_labels[i], framework::LogLevel::DEBUG);
+        }
+    }
+
+    if(num_elements > 0)
+    {
+        const float percent_mismatches = static_cast<float>(num_mismatches) / num_elements * 100.f;
+
+        ARM_COMPUTE_TEST_INFO(num_mismatches << " values (" << std::fixed << std::setprecision(2) << percent_mismatches << "%) mismatched");
+        ARM_COMPUTE_EXPECT_EQUAL(num_mismatches, 0, framework::LogLevel::ERRORS);
     }
 }
 } // namespace validation
diff --git a/tests/validation/Validation.h b/tests/validation/Validation.h
index 865d05b..5e5dab0 100644
--- a/tests/validation/Validation.h
+++ b/tests/validation/Validation.h
@@ -21,43 +21,127 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#ifndef __ARM_COMPUTE_TEST_REFERENCE_VALIDATION_H__
-#define __ARM_COMPUTE_TEST_REFERENCE_VALIDATION_H__
+#ifndef __ARM_COMPUTE_TEST_VALIDATION_H__
+#define __ARM_COMPUTE_TEST_VALIDATION_H__
 
+#include "arm_compute/core/FixedPoint.h"
+#include "arm_compute/core/IArray.h"
 #include "arm_compute/core/Types.h"
+#include "tests/IAccessor.h"
+#include "tests/SimpleTensor.h"
+#include "tests/Types.h"
+#include "tests/Utils.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Exceptions.h"
+#include "utils/TypePrinter.h"
 
-#include "boost_wrapper.h"
-
+#include <iomanip>
+#include <ios>
 #include <vector>
 
 namespace arm_compute
 {
-class Tensor;
-
 namespace test
 {
-class RawTensor;
-class IAccessor;
-
 namespace validation
 {
+/** Class reprensenting an absolute tolerance value. */
 template <typename T>
-boost::test_tools::predicate_result compare_dimensions(const Dimensions<T> &dimensions1, const Dimensions<T> &dimensions2)
+class AbsoluteTolerance
+{
+public:
+    /** Underlying type. */
+    using value_type = T;
+
+    /* Default constructor.
+     *
+     * Initialises the tolerance to 0.
+     */
+    AbsoluteTolerance() = default;
+
+    /** Constructor.
+     *
+     * @param[in] value Absolute tolerance value.
+     */
+    explicit constexpr AbsoluteTolerance(T value)
+        : _value{ value }
+    {
+    }
+
+    /** Implicit conversion to the underlying type. */
+    constexpr operator T() const
+    {
+        return _value;
+    }
+
+private:
+    T _value{ std::numeric_limits<T>::epsilon() };
+};
+
+/** Class reprensenting a relative tolerance value. */
+template <typename T>
+class RelativeTolerance
+{
+public:
+    /** Underlying type. */
+    using value_type = T;
+
+    /* Default constructor.
+     *
+     * Initialises the tolerance to 0.
+     */
+    RelativeTolerance() = default;
+
+    /** Constructor.
+     *
+     * @param[in] value Relative tolerance value.
+     */
+    explicit constexpr RelativeTolerance(value_type value)
+        : _value{ value }
+    {
+    }
+
+    /** Implicit conversion to the underlying type. */
+    constexpr operator value_type() const
+    {
+        return _value;
+    }
+
+private:
+    value_type _value{ std::numeric_limits<T>::epsilon() };
+};
+
+/** Print AbsoluteTolerance type. */
+template <typename T>
+inline ::std::ostream &operator<<(::std::ostream &os, const AbsoluteTolerance<T> &tolerance)
+{
+    os << static_cast<typename AbsoluteTolerance<T>::value_type>(tolerance);
+
+    return os;
+}
+
+/** Print RelativeTolerance type. */
+template <typename T>
+inline ::std::ostream &operator<<(::std::ostream &os, const RelativeTolerance<T> &tolerance)
+{
+    os << static_cast<typename RelativeTolerance<T>::value_type>(tolerance);
+
+    return os;
+}
+
+template <typename T>
+bool compare_dimensions(const Dimensions<T> &dimensions1, const Dimensions<T> &dimensions2)
 {
     if(dimensions1.num_dimensions() != dimensions2.num_dimensions())
     {
-        boost::test_tools::predicate_result result(false);
-        result.message() << "Different dimensionality [" << dimensions1.num_dimensions() << "!=" << dimensions2.num_dimensions() << "]";
-        return result;
+        return false;
     }
 
     for(unsigned int i = 0; i < dimensions1.num_dimensions(); ++i)
     {
         if(dimensions1[i] != dimensions2[i])
         {
-            boost::test_tools::predicate_result result(false);
-            result.message() << "Mismatch in dimension " << i << " [" << dimensions1[i] << "!=" << dimensions2[i] << "]";
-            return result;
+            return false;
         }
     }
 
@@ -88,7 +172,8 @@
  * reference tensor and test tensor is multiple of wrap_range), but such errors would be detected by
  * other test cases.
  */
-void validate(const IAccessor &tensor, const RawTensor &reference, float tolerance_value = 0.f, float tolerance_number = 0.f, uint64_t wrap_range = 0);
+template <typename T, typename U = AbsoluteTolerance<T>>
+void validate(const IAccessor &tensor, const SimpleTensor<T> &reference, U tolerance_value = U(), float tolerance_number = 0.f);
 
 /** Validate tensors with valid region.
  *
@@ -100,7 +185,8 @@
  * reference tensor and test tensor is multiple of wrap_range), but such errors would be detected by
  * other test cases.
  */
-void validate(const IAccessor &tensor, const RawTensor &reference, const ValidRegion &valid_region, float tolerance_value = 0.f, float tolerance_number = 0.f, uint64_t wrap_range = 0);
+template <typename T, typename U = AbsoluteTolerance<T>>
+void validate(const IAccessor &tensor, const SimpleTensor<T> &reference, const ValidRegion &valid_region, U tolerance_value = U(), float tolerance_number = 0.f);
 
 /** Validate tensors against constant value.
  *
@@ -121,7 +207,278 @@
  * - All values should match
  */
 void validate(std::vector<unsigned int> classified_labels, std::vector<unsigned int> expected_labels);
+
+/** Validate float value.
+ *
+ * - All values should match
+ */
+template <typename T, typename U = AbsoluteTolerance<T>>
+bool validate(T target, T reference, U tolerance = AbsoluteTolerance<T>());
+
+/** Validate key points. */
+template <typename T, typename U, typename V = AbsoluteTolerance<float>>
+void validate_keypoints(T target_first, T target_last, U reference_first, U reference_last, V tolerance = AbsoluteTolerance<float>());
+
+template <typename T>
+struct compare_base
+{
+    compare_base(typename T::value_type target, typename T::value_type reference, T tolerance = T(0))
+        : _target{ target }, _reference{ reference }, _tolerance{ tolerance }
+    {
+    }
+
+    typename T::value_type _target{};
+    typename T::value_type _reference{};
+    T                      _tolerance{};
+};
+
+template <typename T>
+struct compare;
+
+template <typename U>
+struct compare<AbsoluteTolerance<U>> : public compare_base<AbsoluteTolerance<U>>
+{
+    using compare_base<AbsoluteTolerance<U>>::compare_base;
+
+    operator bool() const
+    {
+        if(!std::isfinite(this->_target) || !std::isfinite(this->_reference))
+        {
+            return false;
+        }
+        else if(this->_target == this->_reference)
+        {
+            return true;
+        }
+
+        using comparison_type = typename std::conditional<std::is_integral<U>::value, int64_t, U>::type;
+
+        const comparison_type abs_difference(std::abs(static_cast<comparison_type>(this->_target) - static_cast<comparison_type>(this->_reference)));
+
+        return abs_difference <= static_cast<comparison_type>(this->_tolerance);
+    }
+};
+
+template <typename U>
+struct compare<RelativeTolerance<U>> : public compare_base<RelativeTolerance<U>>
+{
+    using compare_base<RelativeTolerance<U>>::compare_base;
+
+    operator bool() const
+    {
+        if(!std::isfinite(this->_target) || !std::isfinite(this->_reference))
+        {
+            return false;
+        }
+        else if(this->_target == this->_reference)
+        {
+            return true;
+        }
+
+        const U epsilon = (std::is_same<half, typename std::remove_cv<U>::type>::value || (this->_reference == 0)) ? static_cast<U>(0.01) : static_cast<U>(1e-05);
+
+        if(std::abs(static_cast<double>(this->_reference) - static_cast<double>(this->_target)) <= epsilon)
+        {
+            return true;
+        }
+        else
+        {
+            if(static_cast<double>(this->_reference) == 0.0f) // We have checked whether _reference and _target is closing. If _reference is 0 but not closed to _target, it should return false
+            {
+                return false;
+            }
+
+            const double relative_change = std::abs(static_cast<double>(this->_target) - static_cast<double>(this->_reference)) / this->_reference;
+
+            return relative_change <= static_cast<U>(this->_tolerance);
+        }
+    }
+};
+
+template <typename T, typename U>
+void validate(const IAccessor &tensor, const SimpleTensor<T> &reference, U tolerance_value, float tolerance_number)
+{
+    // Validate with valid region covering the entire shape
+    validate(tensor, reference, shape_to_valid_region(tensor.shape()), tolerance_value, tolerance_number);
+}
+
+template <typename T, typename U>
+void validate(const IAccessor &tensor, const SimpleTensor<T> &reference, const ValidRegion &valid_region, U tolerance_value, float tolerance_number)
+{
+    int64_t num_mismatches = 0;
+    int64_t num_elements   = 0;
+
+    ARM_COMPUTE_EXPECT_EQUAL(tensor.element_size(), reference.element_size(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT_EQUAL(tensor.data_type(), reference.data_type(), framework::LogLevel::ERRORS);
+
+    if(reference.format() != Format::UNKNOWN)
+    {
+        ARM_COMPUTE_EXPECT_EQUAL(tensor.format(), reference.format(), framework::LogLevel::ERRORS);
+    }
+
+    ARM_COMPUTE_EXPECT_EQUAL(tensor.num_channels(), reference.num_channels(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT(compare_dimensions(tensor.shape(), reference.shape()), framework::LogLevel::ERRORS);
+
+    const int min_elements = std::min(tensor.num_elements(), reference.num_elements());
+    const int min_channels = std::min(tensor.num_channels(), reference.num_channels());
+
+    // Iterate over all elements within valid region, e.g. U8, S16, RGB888, ...
+    for(int element_idx = 0; element_idx < min_elements; ++element_idx)
+    {
+        const Coordinates id = index2coord(reference.shape(), element_idx);
+
+        if(is_in_valid_region(valid_region, id))
+        {
+            // Iterate over all channels within one element
+            for(int c = 0; c < min_channels; ++c)
+            {
+                const T &target_value    = reinterpret_cast<const T *>(tensor(id))[c];
+                const T &reference_value = reinterpret_cast<const T *>(reference(id))[c];
+
+                if(!compare<U>(target_value, reference_value, tolerance_value))
+                {
+                    ARM_COMPUTE_TEST_INFO("id = " << id);
+                    ARM_COMPUTE_TEST_INFO("channel = " << c);
+                    ARM_COMPUTE_TEST_INFO("target = " << std::setprecision(5) << framework::make_printable(target_value));
+                    ARM_COMPUTE_TEST_INFO("reference = " << std::setprecision(5) << framework::make_printable(reference_value));
+                    ARM_COMPUTE_TEST_INFO("tolerance = " << std::setprecision(5) << framework::make_printable(static_cast<typename U::value_type>(tolerance_value)));
+                    framework::ARM_COMPUTE_PRINT_INFO();
+
+                    ++num_mismatches;
+                }
+
+                ++num_elements;
+            }
+        }
+    }
+
+    if(num_elements > 0)
+    {
+        const int64_t absolute_tolerance_number = tolerance_number * num_elements;
+        const float   percent_mismatches        = static_cast<float>(num_mismatches) / num_elements * 100.f;
+
+        ARM_COMPUTE_TEST_INFO(num_mismatches << " values (" << std::fixed << std::setprecision(2) << percent_mismatches
+                              << "%) mismatched (maximum tolerated " << std::setprecision(2) << tolerance_number << "%)");
+        ARM_COMPUTE_EXPECT(num_mismatches <= absolute_tolerance_number, framework::LogLevel::ERRORS);
+    }
+}
+
+/** Check which keypoints from [first1, last1) are missing in [first2, last2) */
+template <typename T, typename U, typename V>
+std::pair<int64_t, int64_t> compare_keypoints(T first1, T last1, U first2, U last2, V tolerance)
+{
+    int64_t num_missing    = 0;
+    int64_t num_mismatches = 0;
+
+    while(first1 != last1)
+    {
+        const auto point = std::find_if(first2, last2, [&](KeyPoint point)
+        {
+            return point.x == first1->x && point.y == first1->y;
+        });
+
+        if(point == last2)
+        {
+            ++num_missing;
+            ARM_COMPUTE_TEST_INFO("keypoint1 = " << *first1)
+            ARM_COMPUTE_EXPECT_FAIL("Key point not found", framework::LogLevel::DEBUG);
+        }
+        else if(!validate(point->tracking_status, first1->tracking_status) || !validate(point->strength, first1->strength, tolerance) || !validate(point->scale, first1->scale)
+                || !validate(point->orientation, first1->orientation) || !validate(point->error, first1->error))
+        {
+            ++num_mismatches;
+            ARM_COMPUTE_TEST_INFO("keypoint1 = " << *first1)
+            ARM_COMPUTE_TEST_INFO("keypoint2 = " << *point)
+            ARM_COMPUTE_EXPECT_FAIL("Mismatching keypoint", framework::LogLevel::DEBUG);
+        }
+
+        ++first1;
+    }
+
+    return std::make_pair(num_missing, num_mismatches);
+}
+
+template <typename T, typename U, typename V>
+void validate_keypoints(T target_first, T target_last, U reference_first, U reference_last, V tolerance)
+{
+    const int64_t num_elements_target    = std::distance(target_first, target_last);
+    const int64_t num_elements_reference = std::distance(reference_first, reference_last);
+
+    ARM_COMPUTE_EXPECT_EQUAL(num_elements_target, num_elements_reference, framework::LogLevel::ERRORS);
+
+    int64_t num_missing    = 0;
+    int64_t num_mismatches = 0;
+
+    if(num_elements_reference > 0)
+    {
+        std::tie(num_missing, num_mismatches) = compare_keypoints(reference_first, reference_last, target_first, target_last, tolerance);
+
+        const float percent_missing    = static_cast<float>(num_missing) / num_elements_reference * 100.f;
+        const float percent_mismatches = static_cast<float>(num_mismatches) / num_elements_reference * 100.f;
+
+        ARM_COMPUTE_TEST_INFO(num_missing << " keypoints (" << std::fixed << std::setprecision(2) << percent_missing << "%) are missing in target");
+        ARM_COMPUTE_EXPECT_EQUAL(num_missing, 0, framework::LogLevel::ERRORS);
+
+        ARM_COMPUTE_TEST_INFO(num_mismatches << " keypoints (" << std::fixed << std::setprecision(2) << percent_mismatches << "%) mismatched");
+        ARM_COMPUTE_EXPECT_EQUAL(num_mismatches, 0, framework::LogLevel::ERRORS);
+    }
+
+    if(num_elements_target > 0)
+    {
+        std::tie(num_missing, num_mismatches) = compare_keypoints(target_first, target_last, reference_first, reference_last, tolerance);
+
+        const float percent_missing = static_cast<float>(num_missing) / num_elements_target * 100.f;
+
+        ARM_COMPUTE_TEST_INFO(num_missing << " keypoints (" << std::fixed << std::setprecision(2) << percent_missing << "%) are not part of target");
+        ARM_COMPUTE_EXPECT_EQUAL(num_missing, 0, framework::LogLevel::ERRORS);
+    }
+}
+
+template <typename T, typename U>
+bool validate(T target, T reference, U tolerance)
+{
+    ARM_COMPUTE_TEST_INFO("reference = " << std::setprecision(5) << framework::make_printable(reference));
+    ARM_COMPUTE_TEST_INFO("target = " << std::setprecision(5) << framework::make_printable(target));
+    ARM_COMPUTE_TEST_INFO("tolerance = " << std::setprecision(5) << framework::make_printable(static_cast<typename U::value_type>(tolerance)));
+
+    const bool equal = compare<U>(target, reference, tolerance);
+
+    ARM_COMPUTE_EXPECT(equal, framework::LogLevel::ERRORS);
+
+    return equal;
+}
+
+template <typename T, typename U>
+void validate_min_max_loc(const MinMaxLocationValues<T> &target, const MinMaxLocationValues<U> &reference)
+{
+    ARM_COMPUTE_EXPECT_EQUAL(target.min, reference.min, framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT_EQUAL(target.max, reference.max, framework::LogLevel::ERRORS);
+
+    ARM_COMPUTE_EXPECT_EQUAL(target.min_loc.size(), reference.min_loc.size(), framework::LogLevel::ERRORS);
+    ARM_COMPUTE_EXPECT_EQUAL(target.max_loc.size(), reference.max_loc.size(), framework::LogLevel::ERRORS);
+
+    for(uint32_t i = 0; i < target.min_loc.size(); ++i)
+    {
+        const auto same_coords = std::find_if(reference.min_loc.begin(), reference.min_loc.end(), [&target, i](Coordinates2D coord)
+        {
+            return coord.x == target.min_loc.at(i).x && coord.y == target.min_loc.at(i).y;
+        });
+
+        ARM_COMPUTE_EXPECT(same_coords != reference.min_loc.end(), framework::LogLevel::ERRORS);
+    }
+
+    for(uint32_t i = 0; i < target.max_loc.size(); ++i)
+    {
+        const auto same_coords = std::find_if(reference.max_loc.begin(), reference.max_loc.end(), [&target, i](Coordinates2D coord)
+        {
+            return coord.x == target.max_loc.at(i).x && coord.y == target.max_loc.at(i).y;
+        });
+
+        ARM_COMPUTE_EXPECT(same_coords != reference.max_loc.end(), framework::LogLevel::ERRORS);
+    }
+}
+
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
-#endif
+#endif /* __ARM_COMPUTE_TEST_REFERENCE_VALIDATION_H__ */
diff --git a/tests/validation/ValidationUserConfiguration.h b/tests/validation/ValidationUserConfiguration.h
deleted file mode 100644
index 28b58e8..0000000
--- a/tests/validation/ValidationUserConfiguration.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2017 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_TEST_REFERENCE_VALIDATION_USER_CONFIGURATION_H__
-#define __ARM_COMPUTE_TEST_REFERENCE_VALIDATION_USER_CONFIGURATION_H__
-
-#include "UserConfiguration.h"
-
-namespace arm_compute
-{
-namespace test
-{
-namespace validation
-{
-// Validation requires no specific configuration
-using ValidationUserConfiguration = UserConfiguration;
-} // namespace validation
-
-extern validation::ValidationUserConfiguration user_config;
-} // namespace test
-} // namespace arm_compute
-#endif
diff --git a/tests/validation/fixtures/ActivationLayerFixture.h b/tests/validation/fixtures/ActivationLayerFixture.h
new file mode 100644
index 0000000..384e63b
--- /dev/null
+++ b/tests/validation/fixtures/ActivationLayerFixture.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2017 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_TEST_ACTIVATION_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_ACTIVATION_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/ActivationLayer.h"
+#include "tests/validation/Helpers.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ActivationValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, bool in_place, ActivationLayerInfo::ActivationFunction function, float alpha_beta, DataType data_type, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        _data_type       = data_type;
+        _function        = function;
+
+        ActivationLayerInfo info(function, alpha_beta, alpha_beta);
+
+        _target    = compute_target(shape, in_place, info, data_type, fractional_bits);
+        _reference = compute_reference(shape, info, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        if(is_data_type_float(_data_type))
+        {
+            float min_bound = 0;
+            float max_bound = 0;
+            std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<T>(_function, _data_type);
+            std::uniform_real_distribution<> distribution(min_bound, max_bound);
+            library->fill(tensor, distribution, 0);
+        }
+        else
+        {
+            int min_bound = 0;
+            int max_bound = 0;
+            std::tie(min_bound, max_bound) = get_activation_layer_test_bounds<T>(_function, _data_type, _fractional_bits);
+            std::uniform_int_distribution<> distribution(min_bound, max_bound);
+            library->fill(tensor, distribution, 0);
+        }
+    }
+
+    TensorType compute_target(const TensorShape &shape, bool in_place, ActivationLayerInfo info, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type, 1, fixed_point_position);
+        TensorType dst = create_tensor<TensorType>(shape, data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType act_layer;
+
+        TensorType *dst_ptr = in_place ? &src : &dst;
+
+        act_layer.configure(&src, dst_ptr, info);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        if(!in_place)
+        {
+            dst.allocator()->allocate();
+            ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+        }
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        act_layer.run();
+
+        if(in_place)
+        {
+            return src;
+        }
+        else
+        {
+            return dst;
+        }
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, ActivationLayerInfo info, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(src);
+
+        return reference::activation_layer<T>(src, info);
+    }
+
+    TensorType                              _target{};
+    SimpleTensor<T>                         _reference{};
+    int                                     _fractional_bits{};
+    DataType                                _data_type{};
+    ActivationLayerInfo::ActivationFunction _function{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ActivationValidationFixture : public ActivationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, bool in_place, ActivationLayerInfo::ActivationFunction function, float alpha_beta, DataType data_type)
+    {
+        ActivationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, in_place, function, alpha_beta, data_type, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_ACTIVATION_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/ArithmeticAdditionFixture.h b/tests/validation/fixtures/ArithmeticAdditionFixture.h
new file mode 100644
index 0000000..02c3ca9
--- /dev/null
+++ b/tests/validation/fixtures/ArithmeticAdditionFixture.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017 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_TEST_ARITHMETIC_ADDITION_FIXTURE
+#define ARM_COMPUTE_TEST_ARITHMETIC_ADDITION_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/ArithmeticAddition.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ArithmeticAdditionValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        _target          = compute_target(shape, data_type0, data_type1, output_data_type, convert_policy, fractional_bits);
+        _reference       = compute_reference(shape, data_type0, data_type1, output_data_type, convert_policy, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy, int fixed_point_position)
+    {
+        // Create tensors
+        TensorType ref_src1 = create_tensor<TensorType>(shape, data_type0, 1, fixed_point_position);
+        TensorType ref_src2 = create_tensor<TensorType>(shape, data_type1, 1, fixed_point_position);
+        TensorType dst      = create_tensor<TensorType>(shape, output_data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType add;
+        add.configure(&ref_src1, &ref_src2, &dst, convert_policy);
+
+        ARM_COMPUTE_EXPECT(ref_src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(ref_src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        ref_src1.allocator()->allocate();
+        ref_src2.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!ref_src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!ref_src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(ref_src1), 0);
+        fill(AccessorType(ref_src2), 1);
+
+        // Compute function
+        add.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy, int fixed_point_position)
+    {
+        // Create reference
+        SimpleTensor<T> ref_src1{ shape, data_type0, 1, fixed_point_position };
+        SimpleTensor<T> ref_src2{ shape, data_type1, 1, fixed_point_position };
+
+        // Fill reference
+        fill(ref_src1, 0);
+        fill(ref_src2, 1);
+
+        return reference::arithmetic_addition<T>(ref_src1, ref_src2, output_data_type, convert_policy);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+};
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ArithmeticAdditionValidationFixture : public ArithmeticAdditionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy)
+    {
+        ArithmeticAdditionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type0, data_type1, output_data_type, convert_policy, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_ARITHMETIC_ADDITION_FIXTURE */
diff --git a/tests/validation/fixtures/ArithmeticSubtractionFixture.h b/tests/validation/fixtures/ArithmeticSubtractionFixture.h
new file mode 100644
index 0000000..2c683d6
--- /dev/null
+++ b/tests/validation/fixtures/ArithmeticSubtractionFixture.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017 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_TEST_ARITHMETIC_SUBTRACTION_FIXTURE
+#define ARM_COMPUTE_TEST_ARITHMETIC_SUBTRACTION_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/ArithmeticSubtraction.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ArithmeticSubtractionValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        _target          = compute_target(shape, data_type0, data_type1, output_data_type, convert_policy, fractional_bits);
+        _reference       = compute_reference(shape, data_type0, data_type1, output_data_type, convert_policy, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy, int fixed_point_position)
+    {
+        // Create tensors
+        TensorType ref_src1 = create_tensor<TensorType>(shape, data_type0, 1, fixed_point_position);
+        TensorType ref_src2 = create_tensor<TensorType>(shape, data_type1, 1, fixed_point_position);
+        TensorType dst      = create_tensor<TensorType>(shape, output_data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType sub;
+        sub.configure(&ref_src1, &ref_src2, &dst, convert_policy);
+
+        ARM_COMPUTE_EXPECT(ref_src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(ref_src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        ref_src1.allocator()->allocate();
+        ref_src2.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!ref_src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!ref_src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(ref_src1), 0);
+        fill(AccessorType(ref_src2), 1);
+
+        // Compute function
+        sub.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy, int fixed_point_position)
+    {
+        // Create reference
+        SimpleTensor<T> ref_src1{ shape, data_type0, 1, fixed_point_position };
+        SimpleTensor<T> ref_src2{ shape, data_type1, 1, fixed_point_position };
+
+        // Fill reference
+        fill(ref_src1, 0);
+        fill(ref_src2, 1);
+
+        return reference::arithmetic_subtraction<T>(ref_src1, ref_src2, output_data_type, convert_policy);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+};
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ArithmeticSubtractionValidationFixture : public ArithmeticSubtractionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type0, DataType data_type1, DataType output_data_type, ConvertPolicy convert_policy)
+    {
+        ArithmeticSubtractionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type0, data_type1, output_data_type, convert_policy, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_ARITHMETIC_SUBTRACTION_FIXTURE */
diff --git a/tests/validation/fixtures/BatchNormalizationLayerFixture.h b/tests/validation/fixtures/BatchNormalizationLayerFixture.h
new file mode 100644
index 0000000..f4772a8
--- /dev/null
+++ b/tests/validation/fixtures/BatchNormalizationLayerFixture.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017 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_TEST_BATCH_NORMALIZATION_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_BATCH_NORMALIZATION_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/BatchNormalizationLayer.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class BatchNormalizationLayerValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape0, TensorShape shape1, float epsilon, DataType dt, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        _data_type       = dt;
+        _target          = compute_target(shape0, shape1, epsilon, dt, fractional_bits);
+        _reference       = compute_reference(shape0, shape1, epsilon, dt, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&src_tensor, U &&mean_tensor, U &&var_tensor, U &&beta_tensor, U &&gamma_tensor)
+    {
+        if(is_data_type_float(_data_type))
+        {
+            float min_bound = 0.f;
+            float max_bound = 0.f;
+            std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<T>();
+            std::uniform_real_distribution<> distribution(min_bound, max_bound);
+            std::uniform_real_distribution<> distribution_var(0, max_bound);
+            library->fill(src_tensor, distribution, 0);
+            library->fill(mean_tensor, distribution, 1);
+            library->fill(var_tensor, distribution_var, 0);
+            library->fill(beta_tensor, distribution, 3);
+            library->fill(gamma_tensor, distribution, 4);
+        }
+        else
+        {
+            int min_bound = 0;
+            int max_bound = 0;
+            std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<T>(_fractional_bits);
+            std::uniform_int_distribution<> distribution(min_bound, max_bound);
+            std::uniform_int_distribution<> distribution_var(0, max_bound);
+            library->fill(src_tensor, distribution, 0);
+            library->fill(mean_tensor, distribution, 1);
+            library->fill(var_tensor, distribution_var, 0);
+            library->fill(beta_tensor, distribution, 3);
+            library->fill(gamma_tensor, distribution, 4);
+        }
+    }
+
+    TensorType compute_target(const TensorShape &shape0, const TensorShape &shape1, float epsilon, DataType dt, int fixed_point_position)
+    {
+        // Create tensors
+        TensorType src   = create_tensor<TensorType>(shape0, dt, 1, fixed_point_position);
+        TensorType dst   = create_tensor<TensorType>(shape0, dt, 1, fixed_point_position);
+        TensorType mean  = create_tensor<TensorType>(shape1, dt, 1, fixed_point_position);
+        TensorType var   = create_tensor<TensorType>(shape1, dt, 1, fixed_point_position);
+        TensorType beta  = create_tensor<TensorType>(shape1, dt, 1, fixed_point_position);
+        TensorType gamma = create_tensor<TensorType>(shape1, dt, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType norm;
+        norm.configure(&src, &dst, &mean, &var, &beta, &gamma, epsilon);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(mean.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(var.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(beta.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(gamma.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+        mean.allocator()->allocate();
+        var.allocator()->allocate();
+        beta.allocator()->allocate();
+        gamma.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!mean.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!var.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!beta.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!gamma.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), AccessorType(mean), AccessorType(var), AccessorType(beta), AccessorType(gamma));
+
+        // Compute function
+        norm.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape0, const TensorShape &shape1, float epsilon, DataType dt, int fixed_point_position)
+    {
+        // Create reference
+        SimpleTensor<T> ref_src{ shape0, dt, 1, fixed_point_position };
+        SimpleTensor<T> ref_mean{ shape1, dt, 1, fixed_point_position };
+        SimpleTensor<T> ref_var{ shape1, dt, 1, fixed_point_position };
+        SimpleTensor<T> ref_beta{ shape1, dt, 1, fixed_point_position };
+        SimpleTensor<T> ref_gamma{ shape1, dt, 1, fixed_point_position };
+
+        // Fill reference
+        fill(ref_src, ref_mean, ref_var, ref_beta, ref_gamma);
+
+        return reference::batch_normalization_layer(ref_src, ref_mean, ref_var, ref_beta, ref_gamma, epsilon, fixed_point_position);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+    DataType        _data_type{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class BatchNormalizationLayerValidationFixture : public BatchNormalizationLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape0, TensorShape shape1, float epsilon, DataType dt)
+    {
+        BatchNormalizationLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape0, shape1, epsilon, dt, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_BATCH_NORMALIZATION_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/BitwiseAndFixture.h b/tests/validation/fixtures/BitwiseAndFixture.h
new file mode 100644
index 0000000..0dfff86
--- /dev/null
+++ b/tests/validation/fixtures/BitwiseAndFixture.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 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_TEST_BITWISE_AND_FIXTURE
+#define ARM_COMPUTE_TEST_BITWISE_AND_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/BitwiseAnd.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class BitwiseAndValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create tensors
+        TensorType src1 = create_tensor<TensorType>(shape, data_type);
+        TensorType src2 = create_tensor<TensorType>(shape, data_type);
+        TensorType dst  = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType bitwise_and;
+
+        bitwise_and.configure(&src1, &src2, &dst);
+
+        ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src1.allocator()->allocate();
+        src2.allocator()->allocate();
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src1), 0);
+        fill(AccessorType(src2), 1);
+
+        // Compute function
+        bitwise_and.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src1{ shape, data_type };
+        SimpleTensor<T> src2{ shape, data_type };
+
+        // Fill reference
+        fill(src1, 0);
+        fill(src2, 1);
+
+        return reference::bitwise_and<T>(src1, src2);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_BITWISE_AND_FIXTURE */
diff --git a/tests/validation/fixtures/BitwiseNotFixture.h b/tests/validation/fixtures/BitwiseNotFixture.h
new file mode 100644
index 0000000..e5bf699
--- /dev/null
+++ b/tests/validation/fixtures/BitwiseNotFixture.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 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_TEST_BITWISE_NOT_FIXTURE
+#define ARM_COMPUTE_TEST_BITWISE_NOT_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/BitwiseNot.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class BitwiseNotValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType bitwise_not;
+
+        bitwise_not.configure(&src, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        bitwise_not.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::bitwise_not<T>(src);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_BITWISE_NOT_FIXTURE */
diff --git a/tests/validation/fixtures/BitwiseOrFixture.h b/tests/validation/fixtures/BitwiseOrFixture.h
new file mode 100644
index 0000000..d61e767
--- /dev/null
+++ b/tests/validation/fixtures/BitwiseOrFixture.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 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_TEST_BITWISE_OR_FIXTURE
+#define ARM_COMPUTE_TEST_BITWISE_OR_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/BitwiseOr.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class BitwiseOrValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create tensors
+        TensorType src1 = create_tensor<TensorType>(shape, data_type);
+        TensorType src2 = create_tensor<TensorType>(shape, data_type);
+        TensorType dst  = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType bitwise_or;
+
+        bitwise_or.configure(&src1, &src2, &dst);
+
+        ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src1.allocator()->allocate();
+        src2.allocator()->allocate();
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src1), 0);
+        fill(AccessorType(src2), 1);
+
+        // Compute function
+        bitwise_or.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src1{ shape, data_type };
+        SimpleTensor<T> src2{ shape, data_type };
+
+        // Fill reference
+        fill(src1, 0);
+        fill(src2, 1);
+
+        return reference::bitwise_or<T>(src1, src2);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_BITWISE_OR_FIXTURE */
diff --git a/tests/validation/fixtures/BitwiseXorFixture.h b/tests/validation/fixtures/BitwiseXorFixture.h
new file mode 100644
index 0000000..16fa8c0
--- /dev/null
+++ b/tests/validation/fixtures/BitwiseXorFixture.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2017 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_TEST_BITWISE_XOR_FIXTURE
+#define ARM_COMPUTE_TEST_BITWISE_XOR_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/BitwiseXor.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class BitwiseXorValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create tensors
+        TensorType src1 = create_tensor<TensorType>(shape, data_type);
+        TensorType src2 = create_tensor<TensorType>(shape, data_type);
+        TensorType dst  = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType bitwise_xor;
+
+        bitwise_xor.configure(&src1, &src2, &dst);
+
+        ARM_COMPUTE_EXPECT(src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src1.allocator()->allocate();
+        src2.allocator()->allocate();
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src1.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!src2.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src1), 0);
+        fill(AccessorType(src2), 1);
+
+        // Compute function
+        bitwise_xor.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src1{ shape, data_type };
+        SimpleTensor<T> src2{ shape, data_type };
+
+        // Fill reference
+        fill(src1, 0);
+        fill(src2, 1);
+
+        return reference::bitwise_xor<T>(src1, src2);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_BITWISE_XOR_FIXTURE */
diff --git a/tests/validation/fixtures/Box3x3Fixture.h b/tests/validation/fixtures/Box3x3Fixture.h
new file mode 100644
index 0000000..a53987a
--- /dev/null
+++ b/tests/validation/fixtures/Box3x3Fixture.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 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_TEST_BOX3X3_FIXTURE
+#define ARM_COMPUTE_TEST_BOX3X3_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/Box3x3.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class Box3x3ValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type, BorderMode border_mode)
+    {
+        std::mt19937                           gen(library->seed());
+        std::uniform_int_distribution<uint8_t> distribution(0, 255);
+        const uint8_t                          constant_border_value = distribution(gen);
+
+        _target    = compute_target(shape, data_type, border_mode, constant_border_value);
+        _reference = compute_reference(shape, data_type, border_mode, constant_border_value);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type, BorderMode border_mode, uint8_t constant_border_value)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType box3x3;
+        box3x3.configure(&src, &dst, border_mode, constant_border_value);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        box3x3.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, BorderMode border_mode, uint8_t constant_border_value)
+    {
+        ARM_COMPUTE_ERROR_ON(data_type != DataType::U8);
+
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        // Compute reference
+        return reference::box3x3<T>(src, border_mode, constant_border_value);
+    }
+
+    BorderMode      _border_mode{};
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_BOX3X3_FIXTURE */
diff --git a/tests/validation/fixtures/ConvolutionLayerFixture.h b/tests/validation/fixtures/ConvolutionLayerFixture.h
new file mode 100644
index 0000000..434291b
--- /dev/null
+++ b/tests/validation/fixtures/ConvolutionLayerFixture.h
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2017 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_TEST_CONVOLUTION_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_CONVOLUTION_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/NEON/NEScheduler.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/ConvolutionLayer.h"
+#include "tests/validation/CPP/Utils.h"
+#include "tests/validation/Helpers.h"
+
+#include <random>
+
+namespace arm_compute
+{
+class NEConvolutionLayer;
+
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ConvolutionValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape input_shape, TensorShape weights_shape, TensorShape bias_shape, TensorShape output_shape, PadStrideInfo info, bool reshape_weights, DataType data_type, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        _data_type       = data_type;
+
+        _target    = compute_target(input_shape, weights_shape, bias_shape, output_shape, info, reshape_weights, data_type, fractional_bits);
+        _reference = compute_reference(input_shape, weights_shape, bias_shape, output_shape, info, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        switch(tensor.data_type())
+        {
+            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,
+                              bool reshape_weights, DataType data_type, int fixed_point_position)
+    {
+        WeightsInfo weights_info(!reshape_weights, weights_shape.x(), weights_shape.y(), weights_shape[3]);
+        TensorShape reshaped_weights_shape(weights_shape);
+
+        if(!reshape_weights)
+        {
+            // Check if its a "fully connected" convolution
+            const bool is_fully_connected_convolution = (output_shape.x() == 1 && output_shape.y() == 1);
+            const bool is_optimised                   = std::is_same<FunctionType, NEConvolutionLayer>::value && NEScheduler::get().cpu_info().CPU >= CPUTarget::ARMV7 && data_type == DataType::F32;
+
+            reshaped_weights_shape.collapse(3);
+
+            if(bias_shape.total_size() > 0)
+            {
+                reshaped_weights_shape.set(0, reshaped_weights_shape.x() + 1);
+            }
+
+            if(is_fully_connected_convolution || is_optimised)
+            {
+                const size_t shape_x = reshaped_weights_shape.x();
+                reshaped_weights_shape.set(0, reshaped_weights_shape.y());
+                reshaped_weights_shape.set(1, shape_x);
+            }
+            else
+            {
+                const int interleave_width = 16 / data_size_from_type(data_type);
+                reshaped_weights_shape.set(0, reshaped_weights_shape.x() * interleave_width);
+                reshaped_weights_shape.set(1, static_cast<unsigned int>(std::ceil(reshaped_weights_shape.y() / static_cast<float>(interleave_width))));
+            }
+        }
+
+        // Create tensors
+        TensorType src     = create_tensor<TensorType>(input_shape, data_type, 1, fixed_point_position);
+        TensorType weights = create_tensor<TensorType>(reshaped_weights_shape, data_type, 1, fixed_point_position);
+        TensorType bias    = create_tensor<TensorType>(bias_shape, data_type, 1, fixed_point_position);
+        TensorType dst     = create_tensor<TensorType>(output_shape, data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType conv;
+        conv.configure(&src, &weights, &bias, &dst, info, weights_info);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        weights.allocator()->allocate();
+        bias.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+
+        if(!reshape_weights)
+        {
+            const bool is_fully_connected_convolution = (output_shape.x() == 1 && output_shape.y() == 1);
+            const bool is_optimised                   = std::is_same<FunctionType, NEConvolutionLayer>::value && NEScheduler::get().cpu_info().CPU >= CPUTarget::ARMV7 && data_type == DataType::F32;
+
+            TensorShape     tmp_weights_shape(weights_shape);
+            SimpleTensor<T> tmp_weights(tmp_weights_shape, data_type, 1, fixed_point_position);
+            SimpleTensor<T> tmp_bias(bias_shape, data_type, 1, fixed_point_position);
+
+            // Fill with original shape
+            fill(tmp_weights, 1);
+            fill(tmp_bias, 2);
+
+            tmp_weights = linearise_weights(tmp_weights, &tmp_bias);
+
+            if(!is_fully_connected_convolution && !is_optimised)
+            {
+                // Transpose with interleave
+                const int interleave_size = 16 / tmp_weights.element_size();
+                tmp_weights               = transpose(std::move(tmp_weights), interleave_size);
+            }
+
+            AccessorType weights_accessor(weights);
+
+            for(int i = 0; i < tmp_weights.num_elements(); ++i)
+            {
+                Coordinates coord = index2coord(tmp_weights.shape(), i);
+                std::copy_n(static_cast<const T *>(tmp_weights(coord)), 1, static_cast<T *>(weights_accessor(coord)));
+            }
+        }
+        else
+        {
+            fill(AccessorType(weights), 1);
+            fill(AccessorType(bias), 2);
+        }
+
+        // Compute NEConvolutionLayer 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,
+                                      DataType data_type, int fixed_point_position)
+    {
+        // Create reference
+        SimpleTensor<T> src{ input_shape, data_type, 1, fixed_point_position };
+        SimpleTensor<T> weights{ weights_shape, data_type, 1, fixed_point_position };
+        SimpleTensor<T> bias{ bias_shape, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(src, 0);
+        fill(weights, 1);
+        fill(bias, 2);
+
+        return reference::convolution_layer<T>(src, weights, bias, output_shape, info);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+    DataType        _data_type{};
+
+private:
+    template <typename U>
+    SimpleTensor<U> linearise_weights(const SimpleTensor<U> &weights, const SimpleTensor<U> *biases = nullptr)
+    {
+        TensorShape dst_shape(weights.shape());
+        dst_shape.collapse(3);
+
+        if(biases != nullptr)
+        {
+            dst_shape.set(0, dst_shape.x() + 1);
+        }
+
+        const size_t shape_x = dst_shape.x();
+        dst_shape.set(0, dst_shape.y());
+        dst_shape.set(1, shape_x);
+
+        SimpleTensor<U> dst(dst_shape, weights.data_type());
+
+        // Don't iterate over biases yet
+        for(int weights_idx = 0; weights_idx < weights.num_elements(); ++weights_idx)
+        {
+            Coordinates weights_coord = index2coord(weights.shape(), weights_idx);
+            const int   dst_row       = weights_idx % weights.shape().total_size_lower(3);
+            Coordinates dst_coord{ weights_coord[3], dst_row, weights_coord[4] };
+            const int   dst_idx = coord2index(dst.shape(), dst_coord);
+
+            dst[dst_idx] = weights[weights_idx];
+        }
+
+        if(biases != nullptr)
+        {
+            // Fill last row with biases
+            for(int bias_idx = 0; bias_idx < biases->num_elements(); ++bias_idx)
+            {
+                Coordinates bias_coord = index2coord(biases->shape(), bias_idx);
+                Coordinates dst_coord{ bias_coord.x(), static_cast<int>(dst.shape().y()) - 1, bias_coord.y() };
+                int         dst_idx = coord2index(dst.shape(), dst_coord);
+
+                dst[dst_idx] = (*biases)[bias_idx];
+            }
+        }
+
+        return dst;
+    }
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ConvolutionValidationFixture : public ConvolutionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape input_shape, TensorShape weights_shape, TensorShape bias_shape, TensorShape output_shape, PadStrideInfo info, bool reshape_weights, DataType data_type)
+    {
+        ConvolutionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(input_shape, weights_shape, bias_shape, output_shape, info, reshape_weights, data_type, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_CONVOLUTION_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/DepthConcatenateLayerFixture.h b/tests/validation/fixtures/DepthConcatenateLayerFixture.h
new file mode 100644
index 0000000..633dba2
--- /dev/null
+++ b/tests/validation/fixtures/DepthConcatenateLayerFixture.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2017 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_TEST_DEPTHCONCATENATE_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_DEPTHCONCATENATE_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/DepthConcatenateLayer.h"
+#include "tests/validation/Helpers.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename ITensorType, typename AccessorType, typename FunctionType, typename T>
+class DepthConcatenateValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        // Create input shapes
+        std::mt19937                    gen(library->seed());
+        std::uniform_int_distribution<> num_dis(2, 6);
+        const int                       num_tensors = num_dis(gen);
+
+        std::vector<TensorShape>         shapes(num_tensors, shape);
+        std::uniform_int_distribution<>  depth_dis(1, 7);
+        std::bernoulli_distribution      mutate_dis(0.25f);
+        std::uniform_real_distribution<> change_dis(-0.25f, 0.f);
+
+        // Generate more shapes based on the input
+        for(auto &s : shapes)
+        {
+            // Set the depth of the tensor
+            s.set(2, depth_dis(gen));
+
+            // Randomly change the first dimension
+            if(mutate_dis(gen))
+            {
+                // Decrease the dimension by a small percentage. Don't increase
+                // as that could make tensor too large. Also the change must be
+                // an even number. Otherwise out depth concatenate fails.
+                s.set(0, s[0] + 2 * static_cast<int>(s[0] * change_dis(gen)));
+            }
+
+            // Repeat the same as above for the second dimension
+            if(mutate_dis(gen))
+            {
+                s.set(1, s[1] + 2 * static_cast<int>(s[1] * change_dis(gen)));
+            }
+        }
+
+        _target    = compute_target(shapes, data_type);
+        _reference = compute_reference(shapes, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(std::vector<TensorShape> shapes, DataType data_type)
+    {
+        std::vector<TensorType>    srcs;
+        std::vector<ITensorType *> src_ptrs;
+
+        // Create tensors
+        srcs.reserve(shapes.size());
+
+        for(const auto &shape : shapes)
+        {
+            srcs.emplace_back(create_tensor<TensorType>(shape, data_type, 1, _fractional_bits));
+            src_ptrs.emplace_back(&srcs.back());
+        }
+
+        TensorShape dst_shape = calculate_depth_concatenate_shape(shapes);
+        TensorType  dst       = create_tensor<TensorType>(dst_shape, data_type, 1, _fractional_bits);
+
+        // Create and configure function
+        FunctionType depth_concat;
+        depth_concat.configure(src_ptrs, &dst);
+
+        for(auto &src : srcs)
+        {
+            ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        }
+
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        for(auto &src : srcs)
+        {
+            src.allocator()->allocate();
+            ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        }
+
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        int i = 0;
+        for(auto &src : srcs)
+        {
+            fill(AccessorType(src), i++);
+        }
+
+        // Compute function
+        depth_concat.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(std::vector<TensorShape> shapes, DataType data_type)
+    {
+        std::vector<SimpleTensor<T>> srcs;
+
+        // Create and fill tensors
+        int i = 0;
+        for(const auto &shape : shapes)
+        {
+            srcs.emplace_back(shape, data_type, 1, _fractional_bits);
+            fill(srcs.back(), i++);
+        }
+
+        return reference::depthconcatenate_layer<T>(srcs);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+
+private:
+    int _fractional_bits{ 1 };
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_DEPTHCONCATENATE_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/DepthConvertFixture.h b/tests/validation/fixtures/DepthConvertFixture.h
new file mode 100644
index 0000000..b132a93
--- /dev/null
+++ b/tests/validation/fixtures/DepthConvertFixture.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2017 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_TEST_DEPTH_CONVERT_FIXTURE
+#define ARM_COMPUTE_TEST_DEPTH_CONVERT_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/DepthConvert.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T1, typename T2>
+class DepthConvertValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift, uint32_t fractional_bits)
+    {
+        _shift           = shift;
+        _fractional_bits = fractional_bits;
+        _target          = compute_target(shape, dt_in, dt_out, policy, shift, fractional_bits);
+        _reference       = compute_reference(shape, dt_in, dt_out, policy, shift, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift, uint32_t fixed_point_position)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, dt_in, 1, static_cast<int>(fixed_point_position));
+        TensorType dst = create_tensor<TensorType>(shape, dt_out, 1, static_cast<int>(fixed_point_position));
+
+        // Create and configure function
+        FunctionType depth_convert;
+        depth_convert.configure(&src, &dst, policy, shift);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+
+        // Compute function
+        depth_convert.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T2> compute_reference(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift, uint32_t fixed_point_position)
+    {
+        // Create reference
+        SimpleTensor<T1> src{ shape, dt_in, 1, static_cast<int>(fixed_point_position) };
+
+        // Fill reference
+        fill(src, 0);
+
+        return reference::depth_convert<T1, T2>(src, dt_out, policy, shift);
+    }
+
+    TensorType       _target{};
+    SimpleTensor<T2> _reference{};
+    int              _fractional_bits{};
+    int              _shift{};
+};
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T1, typename T2>
+class DepthConvertValidationFixture : public DepthConvertValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T1, T2>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t shift)
+    {
+        DepthConvertValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T1, T2>::setup(shape, dt_in, dt_out, policy, shift, 0);
+    }
+};
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T1, typename T2>
+class DepthConvertValidationFractionalBitsFixture : public DepthConvertValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T1, T2>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType dt_in, DataType dt_out, ConvertPolicy policy, uint32_t fractional_bits)
+    {
+        DepthConvertValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T1, T2>::setup(shape, dt_in, dt_out, policy, 0, fractional_bits);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_DEPTH_CONVERT_FIXTURE */
diff --git a/tests/validation/fixtures/DepthwiseConvolutionFixture.h b/tests/validation/fixtures/DepthwiseConvolutionFixture.h
new file mode 100644
index 0000000..4a890f6
--- /dev/null
+++ b/tests/validation/fixtures/DepthwiseConvolutionFixture.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017 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_TEST_DEPTHWISE_CONVOLUTION_FIXTURE
+#define ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/DepthwiseConvolution.h"
+#include "tests/validation/Helpers.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class DepthwiseConvolutionValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape in_shape, TensorShape weights_shape, TensorShape out_shape, PadStrideInfo pad_stride_info)
+    {
+        _target    = compute_target(in_shape, weights_shape, out_shape, pad_stride_info);
+        _reference = compute_reference(in_shape, weights_shape, out_shape, pad_stride_info);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        switch(tensor.data_type())
+        {
+            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 &output_shape, PadStrideInfo &pad_stride_info)
+    {
+        // Create tensors
+        TensorType src     = create_tensor<TensorType>(input_shape, DataType::F32);
+        TensorType weights = create_tensor<TensorType>(weights_shape, DataType::F32);
+        TensorType dst     = create_tensor<TensorType>(output_shape, DataType::F32);
+
+        // Create Depthwise Convolution configure function
+        FunctionType depthwise_convolution;
+        depthwise_convolution.configure(&src, &dst, &weights, pad_stride_info);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        weights.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+        fill(AccessorType(weights), 1);
+
+        // Compute function
+        depthwise_convolution.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &in_shape, const TensorShape &weights_shape, const TensorShape &out_shape, const PadStrideInfo &pad_stride_info)
+    {
+        SimpleTensor<T> src(in_shape, DataType::F32);
+        SimpleTensor<T> weights(weights_shape, DataType::F32);
+
+        fill(src, 0);
+        fill(weights, 1);
+
+        return reference::depthwise_convolution(src, weights, out_shape, pad_stride_info);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_FIXTURE */
diff --git a/tests/validation/fixtures/DepthwiseSeparableConvolutionLayerFixture.h b/tests/validation/fixtures/DepthwiseSeparableConvolutionLayerFixture.h
new file mode 100644
index 0000000..e8f6854
--- /dev/null
+++ b/tests/validation/fixtures/DepthwiseSeparableConvolutionLayerFixture.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2017 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_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/DepthwiseSeparableConvolutionLayer.h"
+#include "tests/validation/Helpers.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class DepthwiseSeparableConvolutionValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape in_shape, TensorShape depthwise_weights_shape, TensorShape depthwise_out_shape, TensorShape pointwise_weights_shape, TensorShape biases_shape, TensorShape output_shape,
+               PadStrideInfo pad_stride_depthwise_info, PadStrideInfo pad_stride_pointwise_info)
+    {
+        _target    = compute_target(in_shape, depthwise_weights_shape, depthwise_out_shape, pointwise_weights_shape, biases_shape, output_shape, pad_stride_depthwise_info, pad_stride_pointwise_info);
+        _reference = compute_reference(in_shape, depthwise_weights_shape, depthwise_out_shape, pointwise_weights_shape, biases_shape, output_shape, pad_stride_depthwise_info, pad_stride_pointwise_info);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        switch(tensor.data_type())
+        {
+            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 &depthwise_weights_shape, const TensorShape &depthwise_out_shape, const TensorShape &pointwise_weights_shape,
+                              const TensorShape &biases_shape,
+                              const TensorShape &output_shape, const PadStrideInfo &pad_stride_depthwise_info, const PadStrideInfo &pad_stride_pointwise_info)
+    {
+        // Create tensors
+        TensorType src               = create_tensor<TensorType>(input_shape, DataType::F32);
+        TensorType depthwise_weights = create_tensor<TensorType>(depthwise_weights_shape, DataType::F32);
+        TensorType depthwise_out     = create_tensor<TensorType>(depthwise_out_shape, DataType::F32);
+        TensorType pointwise_weights = create_tensor<TensorType>(pointwise_weights_shape, DataType::F32);
+        TensorType biases            = create_tensor<TensorType>(biases_shape, DataType::F32);
+        TensorType dst               = create_tensor<TensorType>(output_shape, DataType::F32);
+
+        // Create Depthwise Separable Convolution Layer configure function
+        CLDepthwiseSeparableConvolutionLayer depthwise_separable_convolution_layer;
+        depthwise_separable_convolution_layer.configure(&src, &depthwise_weights, &depthwise_out, &pointwise_weights, &biases, &dst, pad_stride_depthwise_info, pad_stride_pointwise_info);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        depthwise_weights.allocator()->allocate();
+        depthwise_out.allocator()->allocate();
+        pointwise_weights.allocator()->allocate();
+        biases.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!depthwise_weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!depthwise_out.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!pointwise_weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!biases.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+        fill(AccessorType(depthwise_weights), 1);
+        fill(AccessorType(pointwise_weights), 2);
+        fill(AccessorType(biases), 3);
+
+        // Compute function
+        depthwise_separable_convolution_layer.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &in_shape, const TensorShape &depthwise_weights_shape, const TensorShape &depthwise_out_shape, const TensorShape &pointwise_weights_shape,
+                                      const TensorShape &biases_shape, const TensorShape &dst_shape, const PadStrideInfo &pad_stride_depthwise_info, const PadStrideInfo &pad_stride_pointwise_info)
+    {
+        SimpleTensor<T> src(in_shape, DataType::F32);
+        SimpleTensor<T> depthwise_weights(depthwise_weights_shape, DataType::F32);
+        SimpleTensor<T> pointwise_weights(pointwise_weights_shape, DataType::F32);
+        SimpleTensor<T> biases(biases_shape, DataType::F32);
+
+        fill(src, 0);
+        fill(depthwise_weights, 1);
+        fill(pointwise_weights, 2);
+        fill(biases, 3);
+
+        return reference::depthwise_separable_convolution_layer(src, depthwise_weights, depthwise_out_shape, pointwise_weights, biases, dst_shape, pad_stride_depthwise_info, pad_stride_pointwise_info);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_DEPTHWISE_SEPARABLE_CONVOLUTION_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/DequantizationLayerFixture.h b/tests/validation/fixtures/DequantizationLayerFixture.h
new file mode 100644
index 0000000..28d43cf
--- /dev/null
+++ b/tests/validation/fixtures/DequantizationLayerFixture.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2017 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_TEST_DEQUANTIZATION_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_DEQUANTIZATION_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/DequantizationLayer.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class DequantizationValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    template <typename U>
+    void fill_min_max(U &&tensor)
+    {
+        std::mt19937                          gen(library->seed());
+        std::uniform_real_distribution<float> distribution(-1.0f, 1.0f);
+
+        Window window;
+
+        window.set(0, Window::Dimension(0, tensor.shape()[0], 2));
+
+        for(unsigned int d = 1; d < tensor.shape().num_dimensions(); ++d)
+        {
+            window.set(d, Window::Dimension(0, tensor.shape()[d], 1));
+        }
+
+        execute_window_loop(window, [&](const Coordinates & id)
+        {
+            const float n1 = distribution(gen);
+            const float n2 = distribution(gen);
+
+            float min = 0.0f;
+            float max = 0.0f;
+
+            if(n1 < n2)
+            {
+                min = n1;
+                max = n2;
+            }
+            else
+            {
+                min = n2;
+                max = n1;
+            }
+
+            auto out_ptr = reinterpret_cast<float *>(tensor(id));
+            out_ptr[0]   = min;
+            out_ptr[1]   = max;
+        });
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        TensorShape shape_min_max = shape;
+        shape_min_max.set(Window::DimX, 2);
+
+        // Remove Y and Z dimensions and keep the batches
+        shape_min_max.remove_dimension(1);
+        shape_min_max.remove_dimension(1);
+
+        // Create tensors
+        TensorType src     = create_tensor<TensorType>(shape, data_type);
+        TensorType dst     = create_tensor<TensorType>(shape, DataType::F32);
+        TensorType min_max = create_tensor<TensorType>(shape_min_max, DataType::F32);
+
+        // Create and configure function
+        FunctionType dequantization_layer;
+        dequantization_layer.configure(&src, &dst, &min_max);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(min_max.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+        min_max.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!min_max.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+        fill_min_max(AccessorType(min_max));
+
+        // Compute function
+        dequantization_layer.run();
+
+        return dst;
+    }
+
+    SimpleTensor<float> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        TensorShape shape_min_max = shape;
+        shape_min_max.set(Window::DimX, 2);
+
+        // Remove Y and Z dimensions and keep the batches
+        shape_min_max.remove_dimension(1);
+        shape_min_max.remove_dimension(1);
+
+        // Create reference
+        SimpleTensor<T>     src{ shape, data_type };
+        SimpleTensor<float> min_max{ shape_min_max, data_type };
+
+        // Fill reference
+        fill(src);
+        fill_min_max(min_max);
+
+        return reference::dequantization_layer<T>(src, min_max);
+    }
+
+    TensorType          _target{};
+    SimpleTensor<float> _reference{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class DequantizationValidationFixture : public DequantizationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        DequantizationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_DEQUANTIZATION_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/DirectConvolutionLayerFixture.h b/tests/validation/fixtures/DirectConvolutionLayerFixture.h
new file mode 100644
index 0000000..a709157
--- /dev/null
+++ b/tests/validation/fixtures/DirectConvolutionLayerFixture.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2017 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.
+ */
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/ConvolutionLayer.h"
+#include "tests/validation/Helpers.h"
+#include "tests/validation/fixtures/ConvolutionLayerFixture.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class DirectConvolutionValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape input_shape, int stride_x, int stride_y, int pad_x, int pad_y, unsigned int kernel_size, unsigned int num_kernels, DataType data_type, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        _data_type       = data_type;
+
+        const TensorShape   weights_shape(kernel_size, kernel_size, input_shape.z(), num_kernels);
+        const TensorShape   bias_shape(num_kernels);
+        const PadStrideInfo info(stride_x, stride_y, pad_x, pad_y, DimensionRoundingType::FLOOR);
+        const TensorShape   output_shape = get_output_shape(input_shape, weights_shape, info);
+
+        _target    = compute_target(input_shape, weights_shape, bias_shape, output_shape, info, data_type, fractional_bits);
+        _reference = compute_reference(input_shape, weights_shape, bias_shape, output_shape, info, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        switch(tensor.data_type())
+        {
+            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,
+                              DataType data_type, int fixed_point_position)
+    {
+        // Create tensors
+        TensorType src     = create_tensor<TensorType>(input_shape, data_type, 1, fixed_point_position);
+        TensorType weights = create_tensor<TensorType>(weights_shape, data_type, 1, fixed_point_position);
+        TensorType bias    = create_tensor<TensorType>(bias_shape, data_type, 1, fixed_point_position);
+        TensorType dst     = create_tensor<TensorType>(output_shape, data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType conv;
+        conv.configure(&src, &weights, &bias, &dst, info);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        weights.allocator()->allocate();
+        bias.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+        fill(AccessorType(weights), 1);
+        fill(AccessorType(bias), 2);
+
+        // Compute NEConvolutionLayer 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,
+                                      DataType data_type, int fixed_point_position)
+    {
+        // Create reference
+        SimpleTensor<T> src{ input_shape, data_type, 1, fixed_point_position };
+        SimpleTensor<T> weights{ weights_shape, data_type, 1, fixed_point_position };
+        SimpleTensor<T> bias{ bias_shape, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(src, 0);
+        fill(weights, 1);
+        fill(bias, 2);
+
+        return reference::convolution_layer<T>(src, weights, bias, output_shape, info);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+    DataType        _data_type{};
+
+private:
+    TensorShape get_output_shape(TensorShape in_shape, TensorShape kernel_shape, const PadStrideInfo &info)
+    {
+        TensorShape out_shape(in_shape);
+        const std::pair<unsigned int, unsigned int> scaled_dims = scaled_dimensions(in_shape.x(),
+                                                                                    in_shape.y(),
+                                                                                    kernel_shape.x(),
+                                                                                    kernel_shape.y(),
+                                                                                    info);
+        out_shape.set(0, scaled_dims.first);
+        out_shape.set(1, scaled_dims.second);
+        out_shape.set(2, kernel_shape[3]);
+        return out_shape;
+    }
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class DirectConvolutionValidationFixture : public DirectConvolutionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape input_shape, int stride_x, int stride_y, int pad_x, int pad_y, unsigned int kernel_size, unsigned int num_kernels, DataType data_type)
+    {
+        DirectConvolutionValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(input_shape, stride_x, stride_y, pad_x, pad_y, kernel_size, num_kernels, data_type, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/validation/fixtures/FlattenLayerFixture.h b/tests/validation/fixtures/FlattenLayerFixture.h
new file mode 100644
index 0000000..faf53c7
--- /dev/null
+++ b/tests/validation/fixtures/FlattenLayerFixture.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017 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_TEST_FLATTEN_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_FLATTEN_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/core/Utils.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/FlattenLayer.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class FlattenLayerValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _fractional_bits = is_data_type_fixed_point(data_type) ? 4 : 0;
+        _target          = compute_target(shape, data_type);
+        _reference       = compute_reference(shape, data_type);
+        ARM_COMPUTE_ERROR_ON_MISMATCHING_DIMENSIONS(_target.info()->tensor_shape(), _reference.shape());
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        if(_fractional_bits == 0)
+        {
+            std::uniform_real_distribution<> distribution(-1.f, 1.f);
+            library->fill(tensor, distribution, 0);
+        }
+        else
+        {
+            const int                       one_fixed = 1 << _fractional_bits;
+            std::uniform_int_distribution<> distribution(-one_fixed, one_fixed);
+            library->fill(tensor, distribution, 0);
+        }
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        TensorShape shape_flatten(shape);
+        shape_flatten.set(0, shape[0] * shape[1] * shape[2]);
+        shape_flatten.remove_dimension(1);
+        shape_flatten.remove_dimension(1);
+
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type, 1, _fractional_bits);
+        TensorType dst = create_tensor<TensorType>(shape_flatten, data_type, 1, _fractional_bits);
+
+        // Create and configure function
+        FunctionType flatten_layer;
+        flatten_layer.configure(&src, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        flatten_layer.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type, 1, _fractional_bits };
+
+        // Fill reference
+        fill(src);
+
+        return reference::flatten_layer<T>(src);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_FLATTEN_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/FloorFixture.h b/tests/validation/fixtures/FloorFixture.h
new file mode 100644
index 0000000..3f94841
--- /dev/null
+++ b/tests/validation/fixtures/FloorFixture.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017 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_TEST_FLOOR_FIXTURE
+#define ARM_COMPUTE_TEST_FLOOR_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/Floor.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class FloorValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType floor_func;
+        floor_func.configure(&src, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        floor_func.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::floor_layer<T>(src);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_FLOOR_FIXTURE */
diff --git a/tests/validation/fixtures/FullyConnectedLayerFixture.h b/tests/validation/fixtures/FullyConnectedLayerFixture.h
new file mode 100644
index 0000000..b19c40d
--- /dev/null
+++ b/tests/validation/fixtures/FullyConnectedLayerFixture.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2017 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_TEST_FULLY_CONNECTED_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_FULLY_CONNECTED_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/core/Utils.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/RawTensor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/FullyConnectedLayer.h"
+#include "tests/validation/CPP/Utils.h"
+#include "tests/validation/Helpers.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool run_interleave>
+class FullyConnectedLayerValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape input_shape, TensorShape weights_shape, TensorShape bias_shape, TensorShape output_shape, bool transpose_weights, bool reshape_weights, DataType data_type, int fractional_bits)
+    {
+        ARM_COMPUTE_UNUSED(weights_shape);
+        ARM_COMPUTE_UNUSED(bias_shape);
+
+        _fractional_bits = fractional_bits;
+        _data_type       = data_type;
+
+        _target    = compute_target(input_shape, weights_shape, bias_shape, output_shape, transpose_weights, reshape_weights, data_type, fractional_bits);
+        _reference = compute_reference(input_shape, weights_shape, bias_shape, output_shape, transpose_weights, reshape_weights, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        if(is_data_type_float(_data_type))
+        {
+            std::uniform_real_distribution<> distribution(0.5f, 1.f);
+            library->fill(tensor, distribution, i);
+        }
+        else
+        {
+            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, bool transpose_weights,
+                              bool reshape_weights, DataType data_type, int fixed_point_position)
+    {
+        TensorShape reshaped_weights_shape(weights_shape);
+
+        // Test actions depending on the target settings
+        //
+        //            | reshape   | !reshape
+        // -----------+-----------+---------------------------
+        //  transpose |           | ***
+        // -----------+-----------+---------------------------
+        // !transpose | transpose | transpose &
+        //            |           | transpose1xW (if required)
+        //
+        // ***: That combination is invalid. But we can ignore the transpose flag and handle all !reshape the same
+        if(!reshape_weights || !transpose_weights)
+        {
+            const size_t shape_x = reshaped_weights_shape.x();
+            reshaped_weights_shape.set(0, reshaped_weights_shape.y());
+            reshaped_weights_shape.set(1, shape_x);
+
+            // Weights have to be passed reshaped
+            // Transpose 1xW for batched version
+            if(!reshape_weights && output_shape.y() > 1 && run_interleave)
+            {
+                const int   transpose_width = 16 / data_size_from_type(data_type);
+                const float shape_x         = reshaped_weights_shape.x();
+                reshaped_weights_shape.set(0, reshaped_weights_shape.y() * transpose_width);
+                reshaped_weights_shape.set(1, static_cast<unsigned int>(std::ceil(shape_x / transpose_width)));
+            }
+        }
+
+        // Create tensors
+        TensorType src     = create_tensor<TensorType>(input_shape, data_type, 1, fixed_point_position);
+        TensorType weights = create_tensor<TensorType>(reshaped_weights_shape, data_type, 1, fixed_point_position);
+        TensorType bias    = create_tensor<TensorType>(bias_shape, data_type, 1, fixed_point_position);
+        TensorType dst     = create_tensor<TensorType>(output_shape, data_type, 1, fixed_point_position);
+
+        // Create and configure function.
+        FunctionType fc;
+        fc.configure(&src, &weights, &bias, &dst, transpose_weights, !reshape_weights);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        weights.allocator()->allocate();
+        bias.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!weights.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!bias.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+        fill(AccessorType(bias), 2);
+
+        if(!reshape_weights || !transpose_weights)
+        {
+            TensorShape tmp_shape(weights_shape);
+            RawTensor   tmp(tmp_shape, data_type, 1, fixed_point_position);
+
+            // Fill with original shape
+            fill(tmp, 1);
+
+            // Transpose elementwise
+            tmp = transpose(tmp);
+
+            // Reshape weights for batched runs
+            if(!reshape_weights && output_shape.y() > 1 && run_interleave)
+            {
+                // Transpose with interleave
+                const int interleave_size = 16 / tmp.element_size();
+                tmp                       = transpose(tmp, interleave_size);
+            }
+
+            AccessorType weights_accessor(weights);
+
+            for(int i = 0; i < tmp.num_elements(); ++i)
+            {
+                Coordinates coord = index2coord(tmp.shape(), i);
+                std::copy_n(static_cast<const RawTensor::value_type *>(tmp(coord)),
+                            tmp.element_size(),
+                            static_cast<RawTensor::value_type *>(weights_accessor(coord)));
+            }
+        }
+        else
+        {
+            fill(AccessorType(weights), 1);
+        }
+
+        // Compute NEFullyConnectedLayer function
+        fc.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, bool transpose_weights,
+                                      bool reshape_weights, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create reference
+        SimpleTensor<T> src{ input_shape, data_type, 1, fixed_point_position };
+        SimpleTensor<T> weights{ weights_shape, data_type, 1, fixed_point_position };
+        SimpleTensor<T> bias{ bias_shape, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(src, 0);
+        fill(weights, 1);
+        fill(bias, 2);
+
+        return reference::fully_connected_layer<T>(src, weights, bias, output_shape);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+    DataType        _data_type{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool run_interleave>
+class FullyConnectedLayerValidationFixture : public FullyConnectedLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T, run_interleave>
+{
+public:
+    template <typename...>
+    void setup(TensorShape input_shape, TensorShape weights_shape, TensorShape bias_shape, TensorShape output_shape, bool transpose_weights, bool reshape_weights, DataType data_type)
+    {
+        FullyConnectedLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T, run_interleave>::setup(input_shape, weights_shape, bias_shape, output_shape, transpose_weights,
+                                                                                                                         reshape_weights, data_type,
+                                                                                                                         0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_FULLY_CONNECTED_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/GEMMFixture.h b/tests/validation/fixtures/GEMMFixture.h
new file mode 100644
index 0000000..923a29c
--- /dev/null
+++ b/tests/validation/fixtures/GEMMFixture.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2017 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_TEST_GEMM_FIXTURE
+#define ARM_COMPUTE_TEST_GEMM_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/GEMM.h"
+#include "tests/validation/Helpers.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class GEMMValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape_a, TensorShape shape_b, TensorShape shape_c, TensorShape output_shape, float alpha, float beta, DataType data_type, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        _data_type       = data_type;
+
+        _target    = compute_target(shape_a, shape_b, shape_c, output_shape, alpha, beta, data_type, fractional_bits);
+        _reference = compute_reference(shape_a, shape_b, shape_c, output_shape, alpha, beta, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        switch(tensor.data_type())
+        {
+            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 &shape_a, const TensorShape &shape_b, const TensorShape &shape_c, const TensorShape &output_shape, float alpha, float beta,
+                              DataType data_type, int fixed_point_position)
+    {
+        // Create tensors
+        TensorType a   = create_tensor<TensorType>(shape_a, data_type, 1, fixed_point_position);
+        TensorType b   = create_tensor<TensorType>(shape_b, data_type, 1, fixed_point_position);
+        TensorType c   = create_tensor<TensorType>(shape_c, data_type, 1, fixed_point_position);
+        TensorType dst = create_tensor<TensorType>(output_shape, data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType gemm;
+        gemm.configure(&a, &b, &c, &dst, alpha, beta);
+
+        ARM_COMPUTE_EXPECT(a.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(b.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(c.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        a.allocator()->allocate();
+        b.allocator()->allocate();
+        c.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!a.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!b.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!c.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(a), 0);
+        fill(AccessorType(b), 1);
+        fill(AccessorType(c), 2);
+
+        // Compute GEMM function
+        gemm.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape_a, const TensorShape &shape_b, const TensorShape &shape_c, const TensorShape &output_shape, float alpha, float beta,
+                                      DataType data_type, int fixed_point_position)
+    {
+        // Create reference
+        SimpleTensor<T> a{ shape_a, data_type, 1, fixed_point_position };
+        SimpleTensor<T> b{ shape_b, data_type, 1, fixed_point_position };
+        SimpleTensor<T> c{ shape_c, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(a, 0);
+        fill(b, 1);
+        fill(c, 2);
+
+        return reference::gemm<T>(a, b, c, alpha, beta);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+    DataType        _data_type{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class GEMMValidationFixture : public GEMMValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape_a, TensorShape shape_b, TensorShape shape_c, TensorShape output_shape, float alpha, float beta, DataType data_type)
+    {
+        GEMMValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape_a, shape_b, shape_c, output_shape, alpha, beta, data_type, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_GEMM_FIXTURE */
diff --git a/tests/validation/fixtures/Gaussian3x3Fixture.h b/tests/validation/fixtures/Gaussian3x3Fixture.h
new file mode 100644
index 0000000..3b15921
--- /dev/null
+++ b/tests/validation/fixtures/Gaussian3x3Fixture.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 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_TEST_GAUSSIAN3X3_FIXTURE
+#define ARM_COMPUTE_TEST_GAUSSIAN3X3_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/Gaussian3x3.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class Gaussian3x3ValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type, BorderMode border_mode)
+    {
+        std::mt19937                           gen(library->seed());
+        std::uniform_int_distribution<uint8_t> distribution(0, 255);
+        const uint8_t                          constant_border_value = distribution(gen);
+
+        _target    = compute_target(shape, data_type, border_mode, constant_border_value);
+        _reference = compute_reference(shape, data_type, border_mode, constant_border_value);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type, BorderMode border_mode, uint8_t constant_border_value)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType gaussian3x3;
+        gaussian3x3.configure(&src, &dst, border_mode, constant_border_value);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        gaussian3x3.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, BorderMode border_mode, uint8_t constant_border_value)
+    {
+        ARM_COMPUTE_ERROR_ON(data_type != DataType::U8);
+
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        // Compute reference
+        return reference::gaussian3x3<T>(src, border_mode, constant_border_value);
+    }
+
+    BorderMode      _border_mode{};
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_GAUSSIAN3X3_FIXTURE */
diff --git a/tests/validation/fixtures/Gaussian5x5Fixture.h b/tests/validation/fixtures/Gaussian5x5Fixture.h
new file mode 100644
index 0000000..b1f7f28
--- /dev/null
+++ b/tests/validation/fixtures/Gaussian5x5Fixture.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 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_TEST_GAUSSIAN5X5_FIXTURE
+#define ARM_COMPUTE_TEST_GAUSSIAN5X5_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/Gaussian5x5.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class Gaussian5x5ValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type, BorderMode border_mode)
+    {
+        std::mt19937                           gen(library->seed());
+        std::uniform_int_distribution<uint8_t> distribution(0, 255);
+        const uint8_t                          constant_border_value = distribution(gen);
+
+        _target    = compute_target(shape, data_type, border_mode, constant_border_value);
+        _reference = compute_reference(shape, data_type, border_mode, constant_border_value);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type, BorderMode border_mode, uint8_t constant_border_value)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType gaussian5x5;
+        gaussian5x5.configure(&src, &dst, border_mode, constant_border_value);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        gaussian5x5.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, BorderMode border_mode, uint8_t constant_border_value)
+    {
+        ARM_COMPUTE_ERROR_ON(data_type != DataType::U8);
+
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        // Compute reference
+        return reference::gaussian5x5<T>(src, border_mode, constant_border_value);
+    }
+
+    BorderMode      _border_mode{};
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_GAUSSIAN5X5_FIXTURE */
diff --git a/tests/validation/fixtures/HarrisCornersFixture.h b/tests/validation/fixtures/HarrisCornersFixture.h
new file mode 100644
index 0000000..6401905
--- /dev/null
+++ b/tests/validation/fixtures/HarrisCornersFixture.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2017 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_TEST_HARRIS_CORNERS_FIXTURE
+#define ARM_COMPUTE_TEST_HARRIS_CORNERS_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/HarrisCornerDetector.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+class CLHarrisCorners;
+class NEHarrisCorners;
+
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename ArrayType, typename FunctionType, typename T>
+class HarrisCornersValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, int gradient_size, int block_size, BorderMode border_mode, bool use_fp16, Format format)
+    {
+        HarrisCornersParameters params = harris_corners_parameters();
+
+        _target    = compute_target(shape, gradient_size, block_size, border_mode, use_fp16, format, params);
+        _reference = compute_reference(shape, gradient_size, block_size, border_mode, format, params);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    template <typename F, typename std::enable_if<std::is_same<F, NEHarrisCorners>::value, int>::type = 0>
+    void configure_target(F &func, TensorType &src, ArrayType &corners, int gradient_size, int block_size, BorderMode border_mode, bool use_fp16, const HarrisCornersParameters &params)
+    {
+        func.configure(&src, params.threshold, params.min_dist, params.sensitivity, gradient_size, block_size, &corners, border_mode, params.constant_border_value, use_fp16);
+    }
+
+    template <typename F, typename std::enable_if<std::is_same<F, CLHarrisCorners>::value, int>::type = 0>
+    void configure_target(F &func, TensorType &src, ArrayType &corners, int gradient_size, int block_size, BorderMode border_mode, bool use_fp16, const HarrisCornersParameters &params)
+    {
+        ARM_COMPUTE_UNUSED(use_fp16);
+        ARM_COMPUTE_ERROR_ON(use_fp16);
+        func.configure(&src, params.threshold, params.min_dist, params.sensitivity, gradient_size, block_size, &corners, border_mode, params.constant_border_value);
+    }
+
+    ArrayType compute_target(const TensorShape &shape, int gradient_size, int block_size, BorderMode border_mode, bool use_fp16, Format format, const HarrisCornersParameters &params)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type_from_format(format));
+        src.info()->set_format(format);
+
+        // Create array of keypoints
+        ArrayType corners(shape.total_size());
+
+        // Create harris corners configure function
+        FunctionType harris_corners;
+        configure_target<FunctionType>(harris_corners, src, corners, gradient_size, block_size, border_mode, use_fp16, params);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        harris_corners.run();
+
+        return corners;
+    }
+
+    std::vector<KeyPoint> compute_reference(const TensorShape &shape, int gradient_size, int block_size, BorderMode border_mode, Format format, const HarrisCornersParameters &params)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, format };
+
+        // Fill reference
+        fill(src);
+
+        return reference::harris_corner_detector<T>(src, params.threshold, params.min_dist, params.sensitivity, gradient_size, block_size, border_mode, params.constant_border_value);
+    }
+
+    ArrayType             _target{};
+    std::vector<KeyPoint> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_HARRIS_CORNERS_FIXTURE */
diff --git a/tests/validation/fixtures/IntegralImageFixture.h b/tests/validation/fixtures/IntegralImageFixture.h
new file mode 100644
index 0000000..2f0ec51
--- /dev/null
+++ b/tests/validation/fixtures/IntegralImageFixture.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017 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_TEST_INTEGRAL_IMAGE_FIXTURE
+#define ARM_COMPUTE_TEST_INTEGRAL_IMAGE_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/IntegralImage.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class IntegralImageValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, DataType::U8);
+        TensorType dst = create_tensor<TensorType>(shape, DataType::U32);
+
+        // Create and configure function
+        FunctionType integral_image;
+        integral_image.configure(&src, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        integral_image.run();
+
+        return dst;
+    }
+
+    SimpleTensor<uint32_t> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::integral_image<T>(src);
+    }
+
+    TensorType             _target{};
+    SimpleTensor<uint32_t> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_INTEGRAL_IMAGE_FIXTURE */
diff --git a/tests/validation/fixtures/L2NormalizeFixture.h b/tests/validation/fixtures/L2NormalizeFixture.h
new file mode 100644
index 0000000..e611393
--- /dev/null
+++ b/tests/validation/fixtures/L2NormalizeFixture.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017 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_TEST_L2NORMALIZE_FIXTURE
+#define ARM_COMPUTE_TEST_L2NORMALIZE_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/L2Normalize.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class L2NormalizeValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type, unsigned int axis, float epsilon)
+    {
+        _target    = compute_target(shape, data_type, axis, epsilon);
+        _reference = compute_reference(shape, data_type, axis, epsilon);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type, unsigned int axis, float epsilon)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType l2_norm_func;
+        l2_norm_func.configure(&src, &dst, axis, epsilon);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        l2_norm_func.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, unsigned int axis, float epsilon)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::l2_normalize<T>(src, axis, epsilon);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_L2NORMALIZE_FIXTURE */
diff --git a/tests/validation/fixtures/MeanStdDevFixture.h b/tests/validation/fixtures/MeanStdDevFixture.h
new file mode 100644
index 0000000..37f538b
--- /dev/null
+++ b/tests/validation/fixtures/MeanStdDevFixture.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017 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_TEST_MEAN_STD_DEV_FIXTURE
+#define ARM_COMPUTE_TEST_MEAN_STD_DEV_FIXTURE
+
+#include "tests/Globals.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/MeanStdDev.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class MeanStdDevValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    std::pair<float, float> compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+
+        // Create output variables
+        float mean    = 0.0f;
+        float std_dev = 0.0f;
+
+        // Create and configure function
+        FunctionType mean_std_dev;
+        mean_std_dev.configure(&src, &mean, &std_dev);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        mean_std_dev.run();
+
+        return std::make_pair(mean, std_dev);
+    }
+
+    std::pair<float, float> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        // Compute reference
+        return reference::mean_and_standard_deviation<T>(src);
+    }
+
+    std::pair<float, float> _target{};
+    std::pair<float, float> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_MEAN_STD_DEV_FIXTURE */
diff --git a/tests/validation/fixtures/MinMaxLocationFixture.h b/tests/validation/fixtures/MinMaxLocationFixture.h
new file mode 100644
index 0000000..bf076ef
--- /dev/null
+++ b/tests/validation/fixtures/MinMaxLocationFixture.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 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_TEST_MIN_MAX_LOCATION_FIXTURE
+#define ARM_COMPUTE_TEST_MIN_MAX_LOCATION_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/Types.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/MinMaxLocation.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename ArrayType, typename ArrayAccessorType, typename FunctionType, typename T>
+class MinMaxLocationValidationFixture : public framework::Fixture
+{
+public:
+    using target_type = typename std::conditional<std::is_integral<T>::value, int32_t, float>::type;
+
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    MinMaxLocationValues<target_type> compute_target(const TensorShape &shape, DataType data_type)
+    {
+        MinMaxLocationValues<target_type> target;
+
+        ArrayType min_loc(shape.total_size());
+        ArrayType max_loc(shape.total_size());
+
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType min_max_loc;
+        min_max_loc.configure(&src, &target.min, &target.max, &min_loc, &max_loc);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        min_max_loc.run();
+
+        // Create accessor objects for mapping operations
+        ArrayAccessorType min_loc_accessor(min_loc);
+        ArrayAccessorType max_loc_accessor(max_loc);
+
+        // Move min Coordinates2D values from ArrayType to vector
+        for(size_t i = 0; i < min_loc.num_values(); ++i)
+        {
+            target.min_loc.push_back(std::move(min_loc_accessor.at(i)));
+        }
+
+        // Move max Coordinates2D values from ArrayType to vector
+        for(size_t i = 0; i < max_loc.num_values(); ++i)
+        {
+            target.max_loc.push_back(std::move(max_loc_accessor.at(i)));
+        }
+
+        return target;
+    }
+
+    MinMaxLocationValues<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::min_max_location<T>(src);
+    }
+
+    MinMaxLocationValues<target_type> _target{};
+    MinMaxLocationValues<T>           _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_MIN_MAX_LOCATION_FIXTURE */
diff --git a/tests/validation/fixtures/NonLinearFilterFixture.h b/tests/validation/fixtures/NonLinearFilterFixture.h
new file mode 100644
index 0000000..2f22873
--- /dev/null
+++ b/tests/validation/fixtures/NonLinearFilterFixture.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2017 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_TEST_NONLINEAR_FILTER_FIXTURE
+#define ARM_COMPUTE_TEST_NONLINEAR_FILTER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/NonLinearFilter.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class NonLinearFilterValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, NonLinearFilterFunction function, unsigned int mask_size, MatrixPattern pattern, BorderMode border_mode, DataType data_type)
+    {
+        std::mt19937                           generator(library->seed());
+        std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
+        const uint8_t                          constant_border_value = distribution_u8(generator);
+
+        // Create the mask
+        std::vector<uint8_t> mask(mask_size * mask_size);
+        fill_mask_from_pattern(mask.data(), mask_size, mask_size, pattern);
+
+        _border_size = BorderSize(static_cast<int>(mask_size / 2));
+        _target      = compute_target(shape, data_type, function, mask_size, pattern, mask.data(), border_mode, constant_border_value);
+        _reference   = compute_reference(shape, data_type, function, mask_size, pattern, mask.data(), border_mode, constant_border_value);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type, NonLinearFilterFunction function, unsigned int mask_size, MatrixPattern pattern, const uint8_t *mask, BorderMode border_mode,
+                              uint8_t constant_border_value)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType non_linear_filter;
+        non_linear_filter.configure(&src, &dst, function, mask_size, pattern, mask, border_mode, constant_border_value);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        non_linear_filter.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, NonLinearFilterFunction function, unsigned int mask_size, MatrixPattern pattern, const uint8_t *mask,
+                                      BorderMode border_mode, uint8_t constant_border_value)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::non_linear_filter<T>(src, function, mask_size, pattern, mask, border_mode, constant_border_value);
+    }
+
+    BorderMode      _border_mode{};
+    BorderSize      _border_size{};
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_NONLINEAR_FILTER_FIXTURE */
diff --git a/tests/validation/fixtures/NormalizationLayerFixture.h b/tests/validation/fixtures/NormalizationLayerFixture.h
new file mode 100644
index 0000000..696d14f
--- /dev/null
+++ b/tests/validation/fixtures/NormalizationLayerFixture.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017 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_TEST_NORMALIZATION_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_NORMALIZATION_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/NormalizationLayer.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class NormalizationValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, NormType norm_type, int norm_size, float beta, DataType data_type, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        NormalizationLayerInfo info(norm_type, norm_size, 5, beta);
+
+        _target    = compute_target(shape, info, data_type, fractional_bits);
+        _reference = compute_reference(shape, info, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        if(_fractional_bits == 0)
+        {
+            library->fill_tensor_uniform(tensor, 0);
+        }
+        else
+        {
+            const int                       one_fixed = 1 << _fractional_bits;
+            std::uniform_int_distribution<> distribution(-one_fixed, one_fixed);
+            library->fill(tensor, distribution, 0);
+        }
+    }
+
+    TensorType compute_target(const TensorShape &shape, NormalizationLayerInfo info, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type, 1, fixed_point_position);
+        TensorType dst = create_tensor<TensorType>(shape, data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType norm_layer;
+        norm_layer.configure(&src, &dst, info);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        norm_layer.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, NormalizationLayerInfo info, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(src);
+
+        return reference::normalization_layer<T>(src, info);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class NormalizationValidationFixture : public NormalizationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, NormType norm_type, int norm_size, float beta, DataType data_type)
+    {
+        NormalizationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, norm_type, norm_size, beta, data_type, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_NORMALIZATION_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/PoolingLayerFixture.h b/tests/validation/fixtures/PoolingLayerFixture.h
new file mode 100644
index 0000000..775c412
--- /dev/null
+++ b/tests/validation/fixtures/PoolingLayerFixture.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017 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_TEST_POOLING_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_POOLING_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/PoolingLayer.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class PoolingLayerValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, PoolingType pool_type, int pool_size, PadStrideInfo pad_stride_info, DataType data_type, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+        PoolingLayerInfo info(pool_type, pool_size, pad_stride_info);
+
+        _target    = compute_target(shape, info, data_type, fractional_bits);
+        _reference = compute_reference(shape, info, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        if(_fractional_bits == 0)
+        {
+            std::uniform_real_distribution<> distribution(-1.f, 1.f);
+            library->fill(tensor, distribution, 0);
+        }
+        else
+        {
+            const int                       one_fixed = 1 << _fractional_bits;
+            std::uniform_int_distribution<> distribution(-one_fixed, one_fixed);
+            library->fill(tensor, distribution, 0);
+        }
+    }
+
+    TensorType compute_target(const TensorShape &shape, PoolingLayerInfo info, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type, 1, fixed_point_position);
+        TensorType dst;
+
+        // Create and configure function
+        FunctionType pool_layer;
+        pool_layer.configure(&src, &dst, info);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        pool_layer.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, PoolingLayerInfo info, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(src);
+
+        return reference::pooling_layer<T>(src, info);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class PoolingLayerValidationFixture : public PoolingLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, PoolingType pool_type, int pool_size, PadStrideInfo pad_stride_info, DataType data_type)
+    {
+        PoolingLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, pool_type, pool_size, pad_stride_info, data_type, 0);
+    }
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class GlobalPoolingLayerValidationFixture : public PoolingLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, PoolingType pool_type, DataType data_type)
+    {
+        PoolingLayerValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, pool_type, shape.x(), PadStrideInfo(1, 1, 0, 0), data_type, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_POOLING_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/QuantizationLayerFixture.h b/tests/validation/fixtures/QuantizationLayerFixture.h
new file mode 100644
index 0000000..83ee049
--- /dev/null
+++ b/tests/validation/fixtures/QuantizationLayerFixture.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017 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_TEST_QUANTIZATION_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_QUANTIZATION_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/QuantizationLayer.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class QuantizationValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, DataType::U8);
+
+        // Create and configure function
+        FunctionType quantization_layer;
+        quantization_layer.configure(&src, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        quantization_layer.run();
+
+        return dst;
+    }
+
+    SimpleTensor<uint8_t> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::quantization_layer<T>(src);
+    }
+
+    TensorType            _target{};
+    SimpleTensor<uint8_t> _reference{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class QuantizationValidationFixture : public QuantizationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        QuantizationValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_QUANTIZATION_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/ReductionOperationFixture.h b/tests/validation/fixtures/ReductionOperationFixture.h
new file mode 100644
index 0000000..7c871ae
--- /dev/null
+++ b/tests/validation/fixtures/ReductionOperationFixture.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 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_TEST_REDUCTION_OPERATION_FIXTURE
+#define ARM_COMPUTE_TEST_REDUCTION_OPERATION_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/ReductionOperation.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ReductionOperationValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type, unsigned int axis, ReductionOperation op)
+    {
+        const TensorShape output_shape = get_output_shape(shape, axis);
+        _target                        = compute_target(shape, output_shape, data_type, axis, op);
+        _reference                     = compute_reference(shape, output_shape, data_type, axis, op);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &src_shape, const TensorShape &dst_shape, DataType data_type, unsigned int axis, ReductionOperation op)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(src_shape, data_type);
+        TensorType dst = create_tensor<TensorType>(dst_shape, data_type);
+
+        // Create and configure function
+        FunctionType reduction_func;
+        reduction_func.configure(&src, &dst, axis, op);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        reduction_func.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &src_shape, const TensorShape &dst_shape, DataType data_type, unsigned int axis, ReductionOperation op)
+    {
+        // Create reference
+        SimpleTensor<T> src{ src_shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::reduction_operation<T>(src, dst_shape, axis, op);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+
+private:
+    TensorShape get_output_shape(TensorShape shape, unsigned int axis)
+    {
+        TensorShape output_shape(shape);
+        output_shape.set(axis, 1);
+        return output_shape;
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_REDUCTION_OPERATION_FIXTURE */
diff --git a/tests/validation/fixtures/ReshapeLayerFixture.h b/tests/validation/fixtures/ReshapeLayerFixture.h
new file mode 100644
index 0000000..435717c
--- /dev/null
+++ b/tests/validation/fixtures/ReshapeLayerFixture.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2017 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_TEST_RESHAPE_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_RESHAPE_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/ReshapeLayer.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ReshapeLayerValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape input_shape, TensorShape output_shape, DataType data_type)
+    {
+        _target    = compute_target(input_shape, output_shape, data_type);
+        _reference = compute_reference(input_shape, output_shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &input_shape, const TensorShape &output_shape, DataType data_type)
+    {
+        // Check if indeed the input shape can be reshape to the output one
+        ARM_COMPUTE_EXPECT(input_shape.total_size() == output_shape.total_size(), framework::LogLevel::ERRORS);
+
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(input_shape, data_type);
+        TensorType dst = create_tensor<TensorType>(output_shape, data_type);
+
+        // Create and configure function
+        FunctionType reshape;
+
+        reshape.configure(&src, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+
+        // Compute function
+        reshape.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &input_shape, const TensorShape &output_shape, DataType data_type)
+    {
+        // Create reference
+        SimpleTensor<T> src{ input_shape, data_type };
+
+        // Fill reference
+        fill(src, 0);
+
+        return reference::reshape_layer<T>(src, output_shape);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_RESHAPE_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/ScaleFixture.h b/tests/validation/fixtures/ScaleFixture.h
new file mode 100644
index 0000000..476985e
--- /dev/null
+++ b/tests/validation/fixtures/ScaleFixture.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2017 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_TEST_SCALE_FIXTURE
+#define ARM_COMPUTE_TEST_SCALE_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/Scale.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ScaleValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type, InterpolationPolicy policy, BorderMode border_mode)
+    {
+        constexpr float max_width  = 8192.0f;
+        constexpr float max_height = 6384.0f;
+
+        _shape       = shape;
+        _policy      = policy;
+        _border_mode = border_mode;
+        _data_type   = data_type;
+
+        std::mt19937                          generator(library->seed());
+        std::uniform_real_distribution<float> distribution_float(0.25, 3);
+        float                                 scale_x = distribution_float(generator);
+        float                                 scale_y = distribution_float(generator);
+
+        scale_x = ((shape.x() * scale_x) > max_width) ? (max_width / shape.x()) : scale_x;
+        scale_y = ((shape.y() * scale_y) > max_height) ? (max_height / shape.y()) : scale_y;
+
+        std::uniform_int_distribution<uint8_t> distribution_u8(0, 255);
+        T                                      constant_border_value = static_cast<T>(distribution_u8(generator));
+
+        _target    = compute_target(shape, scale_x, scale_y, policy, border_mode, constant_border_value);
+        _reference = compute_reference(shape, scale_x, scale_y, policy, border_mode, constant_border_value);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, const float scale_x, const float scale_y,
+                              InterpolationPolicy policy, BorderMode border_mode, T constant_border_value)
+    {
+        // Create tensors
+        TensorType  src = create_tensor<TensorType>(shape, _data_type);
+        TensorShape shape_scaled(shape);
+        shape_scaled.set(0, shape[0] * scale_x);
+        shape_scaled.set(1, shape[1] * scale_y);
+        TensorType dst = create_tensor<TensorType>(shape_scaled, _data_type);
+
+        // Create and configure function
+        FunctionType scale;
+
+        scale.configure(&src, &dst, policy, border_mode, constant_border_value);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        scale.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, const float scale_x, const float scale_y,
+                                      InterpolationPolicy policy, BorderMode border_mode, T constant_border_value)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, _data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::scale<T>(src, scale_x, scale_y, policy, border_mode, constant_border_value);
+    }
+
+    TensorType          _target{};
+    SimpleTensor<T>     _reference{};
+    TensorShape         _shape{};
+    InterpolationPolicy _policy{};
+    BorderMode          _border_mode{};
+    DataType            _data_type{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_SCALE_FIXTURE */
diff --git a/tests/validation/fixtures/SobelFixture.h b/tests/validation/fixtures/SobelFixture.h
new file mode 100644
index 0000000..2a592b8
--- /dev/null
+++ b/tests/validation/fixtures/SobelFixture.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2017 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_TEST_SOBEL_FIXTURE
+#define ARM_COMPUTE_TEST_SOBEL_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "support/ToolchainSupport.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/Sobel.h"
+
+#include <memory>
+
+namespace arm_compute
+{
+class CLSobel3x3;
+class CLSobel5x5;
+class CLSobel7x7;
+class NESobel3x3;
+class NESobel5x5;
+class NESobel7x7;
+
+namespace test
+{
+namespace validation
+{
+namespace
+{
+template <typename Function>
+struct info;
+
+template <>
+struct info<NESobel3x3>
+{
+    static const Format dst_format  = Format::S16;
+    static const int    filter_size = 3;
+};
+
+template <>
+struct info<CLSobel3x3>
+{
+    static const Format dst_format  = Format::S16;
+    static const int    filter_size = 3;
+};
+
+template <>
+struct info<NESobel5x5>
+{
+    static const Format dst_format  = Format::S16;
+    static const int    filter_size = 5;
+};
+
+template <>
+struct info<CLSobel5x5>
+{
+    static const Format dst_format  = Format::S16;
+    static const int    filter_size = 5;
+};
+
+template <>
+struct info<NESobel7x7>
+{
+    static const Format dst_format  = Format::S32;
+    static const int    filter_size = 7;
+};
+
+template <>
+struct info<CLSobel7x7>
+{
+    static const Format dst_format  = Format::S32;
+    static const int    filter_size = 7;
+};
+} // namespace
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename U>
+class SobelValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, BorderMode border_mode, Format format)
+    {
+        // Generate a random constant value
+        std::mt19937                           gen(library->seed());
+        std::uniform_int_distribution<uint8_t> int_dist(0, 255);
+        const uint8_t                          constant_border_value = int_dist(gen);
+
+        _border_mode = border_mode;
+        _target      = compute_target(shape, border_mode, format, constant_border_value);
+        _reference   = compute_reference(shape, info<FunctionType>::filter_size, border_mode, format, constant_border_value);
+    }
+
+protected:
+    template <typename V>
+    void fill(V &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    std::pair<TensorType, TensorType> compute_target(const TensorShape &shape, BorderMode border_mode, Format format, uint8_t constant_border_value)
+    {
+        // Create tensors
+        TensorType src   = create_tensor<TensorType>(shape, data_type_from_format(format));
+        TensorType dst_x = create_tensor<TensorType>(shape, data_type_from_format(info<FunctionType>::dst_format));
+        TensorType dst_y = create_tensor<TensorType>(shape, data_type_from_format(info<FunctionType>::dst_format));
+
+        src.info()->set_format(format);
+        dst_x.info()->set_format(info<FunctionType>::dst_format);
+        dst_y.info()->set_format(info<FunctionType>::dst_format);
+
+        FunctionType sobel;
+        sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst_x.allocator()->allocate();
+        dst_y.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        sobel.run();
+
+        return std::make_pair(std::move(dst_x), std::move(dst_y));
+    }
+
+    std::pair<SimpleTensor<U>, SimpleTensor<U>> compute_reference(const TensorShape &shape, int filter_size, BorderMode border_mode, Format format, uint8_t constant_border_value)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, format };
+
+        // Fill reference
+        fill(src);
+
+        return reference::sobel<U>(src, filter_size, border_mode, constant_border_value);
+    }
+
+    BorderMode _border_mode{ BorderMode::UNDEFINED };
+    std::pair<TensorType, TensorType>           _target{};
+    std::pair<SimpleTensor<U>, SimpleTensor<U>> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_SOBEL_FIXTURE */
diff --git a/tests/validation/fixtures/SoftmaxLayerFixture.h b/tests/validation/fixtures/SoftmaxLayerFixture.h
new file mode 100644
index 0000000..9c8f044
--- /dev/null
+++ b/tests/validation/fixtures/SoftmaxLayerFixture.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017 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_TEST_SOFTMAX_LAYER_FIXTURE
+#define ARM_COMPUTE_TEST_SOFTMAX_LAYER_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "arm_compute/runtime/Tensor.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/SoftmaxLayer.h"
+
+#include <random>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class SoftmaxValidationFixedPointFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type, int fractional_bits)
+    {
+        _fractional_bits = fractional_bits;
+
+        _target    = compute_target(shape, data_type, fractional_bits);
+        _reference = compute_reference(shape, data_type, fractional_bits);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        if(_fractional_bits == 0)
+        {
+            std::uniform_real_distribution<> distribution(-1000.f, 1000.f);
+            library->fill(tensor, distribution, 0);
+        }
+        else
+        {
+            const int                       one_fixed = 1 << _fractional_bits;
+            std::uniform_int_distribution<> distribution(-one_fixed, one_fixed);
+            library->fill(tensor, distribution, 0);
+        }
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type, 1, fixed_point_position);
+        TensorType dst = create_tensor<TensorType>(shape, data_type, 1, fixed_point_position);
+
+        // Create and configure function
+        FunctionType smx_layer;
+        smx_layer.configure(&src, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        smx_layer.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, int fixed_point_position = 0)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type, 1, fixed_point_position };
+
+        // Fill reference
+        fill(src);
+
+        return reference::softmax_layer<T>(src);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+    int             _fractional_bits{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class SoftmaxValidationFixture : public SoftmaxValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        SoftmaxValidationFixedPointFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, 0);
+    }
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_SOFTMAX_LAYER_FIXTURE */
diff --git a/tests/validation/fixtures/TableLookupFixture.h b/tests/validation/fixtures/TableLookupFixture.h
new file mode 100644
index 0000000..49e0f41
--- /dev/null
+++ b/tests/validation/fixtures/TableLookupFixture.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2017 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_TEST_TABLE_LOOKUP_FIXTURE
+#define ARM_COMPUTE_TEST_TABLE_LOOKUP_FIXTURE
+
+#include "arm_compute/core/TensorShape.h"
+#include "arm_compute/core/Types.h"
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/RawLutAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/TableLookup.h"
+#include "tests/validation/Helpers.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename LutAccessorType, typename LutType, typename T>
+class TableLookupValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type);
+        _reference = compute_reference(shape, data_type);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor, int i)
+    {
+        library->fill_tensor_uniform(tensor, i);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type)
+    {
+        // Create Lut
+        const int num_elem = (data_type == DataType::U8) ? std::numeric_limits<uint8_t>::max() + 1 : std::numeric_limits<int16_t>::max() - std::numeric_limits<int16_t>::lowest() + 1;
+        LutType   lut(num_elem, data_type);
+
+        //Fill the Lut
+        fill_lookuptable(LutAccessorType(lut));
+
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType table_lookup;
+        table_lookup.configure(&src, &lut, &dst);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src), 0);
+        fill(AccessorType(dst), 1);
+
+        // Compute function
+        table_lookup.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type)
+    {
+        // Create rawLut
+        std::map<T, T> rawlut;
+
+        // Fill the Lut
+        fill_lookuptable(RawLutAccessor<T>(rawlut));
+
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src, 0);
+
+        return reference::table_lookup(src, rawlut);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_TABLE_LOOKUP_FIXTURE */
diff --git a/tests/validation/fixtures/ThresholdFixture.h b/tests/validation/fixtures/ThresholdFixture.h
new file mode 100644
index 0000000..0ea43a5
--- /dev/null
+++ b/tests/validation/fixtures/ThresholdFixture.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017 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_TEST_THRESHOLD_FIXTURE
+#define ARM_COMPUTE_TEST_THRESHOLD_FIXTURE
+
+#include "tests/AssetsLibrary.h"
+#include "tests/Globals.h"
+#include "tests/IAccessor.h"
+#include "tests/framework/Asserts.h"
+#include "tests/framework/Fixture.h"
+#include "tests/validation/CPP/Threshold.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace validation
+{
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ThresholdValidationFixture : public framework::Fixture
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper, DataType data_type)
+    {
+        _target    = compute_target(shape, data_type, threshold, false_value, true_value, type, upper);
+        _reference = compute_reference(shape, data_type, threshold, false_value, true_value, type, upper);
+    }
+
+protected:
+    template <typename U>
+    void fill(U &&tensor)
+    {
+        library->fill_tensor_uniform(tensor, 0);
+    }
+
+    TensorType compute_target(const TensorShape &shape, DataType data_type,
+                              uint8_t threshold, uint8_t false_value, uint8_t true_value,
+                              ThresholdType type, uint8_t upper)
+    {
+        // Create tensors
+        TensorType src = create_tensor<TensorType>(shape, data_type);
+        TensorType dst = create_tensor<TensorType>(shape, data_type);
+
+        // Create and configure function
+        FunctionType thrsh;
+        thrsh.configure(&src, &dst, threshold, false_value, true_value, type, upper);
+
+        ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Allocate tensors
+        src.allocator()->allocate();
+        dst.allocator()->allocate();
+        ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+        ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+        // Fill tensors
+        fill(AccessorType(src));
+
+        // Compute function
+        thrsh.run();
+
+        return dst;
+    }
+
+    SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type,
+                                      uint8_t threshold, uint8_t false_value, uint8_t true_value,
+                                      ThresholdType type, uint8_t upper)
+    {
+        // Create reference
+        SimpleTensor<T> src{ shape, data_type };
+
+        // Fill reference
+        fill(src);
+
+        return reference::threshold<T>(src, threshold, false_value, true_value, type, upper);
+    }
+
+    TensorType      _target{};
+    SimpleTensor<T> _reference{};
+};
+} // namespace validation
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_THRESHOLD_FIXTURE */
diff --git a/tests/validation/main.cpp b/tests/validation/main.cpp
deleted file mode 100644
index 844ee36..0000000
--- a/tests/validation/main.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2017 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.
- */
-#define BOOST_TEST_ALTERNATIVE_INIT_API
-
-#include "Globals.h"
-#include "TensorLibrary.h"
-#include "Utils.h"
-#include "ValidationProgramOptions.h"
-#include "ValidationUserConfiguration.h"
-
-#include "arm_compute/runtime/Scheduler.h"
-
-#include "boost_wrapper.h"
-
-#include <iostream>
-#include <memory>
-#include <random>
-
-using namespace arm_compute::test;
-using namespace arm_compute::test::validation;
-
-namespace arm_compute
-{
-namespace test
-{
-ValidationUserConfiguration    user_config;
-std::unique_ptr<TensorLibrary> library;
-} // namespace test
-} // namespace arm_compute
-
-struct GlobalFixture
-{
-    GlobalFixture()
-    {
-        if(user_config.seed.is_set())
-        {
-            library = cpp14::make_unique<TensorLibrary>(user_config.path.get(), user_config.seed);
-        }
-        else
-        {
-            library = cpp14::make_unique<TensorLibrary>(user_config.path.get());
-        }
-
-        BOOST_TEST_MESSAGE("Seed: " << library->seed());
-    }
-};
-
-BOOST_GLOBAL_FIXTURE(GlobalFixture);
-
-bool init_unit_test()
-{
-    boost::unit_test::framework::master_test_suite().p_name.value = "Compute Library Validation Tests";
-
-    ValidationProgramOptions options;
-
-    int   &argc = boost::unit_test::framework::master_test_suite().argc;
-    char **argv = boost::unit_test::framework::master_test_suite().argv;
-
-    try
-    {
-        options.parse_commandline(argc, argv);
-
-        if(options.wants_help())
-        {
-            std::cout << "Usage: " << argv[0] << " [options] PATH\n";
-            std::cout << options.get_help() << "\n";
-            return false;
-        }
-
-        user_config = ValidationUserConfiguration(options);
-    }
-    catch(const boost::program_options::required_option &err)
-    {
-        std::cerr << "Error: " << err.what() << "\n";
-        std::cout << "\nUsage: " << argv[0] << " [options] PATH\n";
-        std::cout << options.get_help() << "\n";
-        return false;
-    }
-
-    std::cout << "Using " << user_config.threads << " CPU " << (user_config.threads == 1 ? "thread" : "threads") << "\n";
-    arm_compute::Scheduler::get().set_num_threads(user_config.threads);
-    return true;
-}