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 ®ion, 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 ¶ms)
+ {
+ 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 ¶ms)
+ {
+ 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 ¶ms)
+ {
+ // 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 ¶ms)
+ {
+ // 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;
-}