aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/validation/CL/ActivationLayer.cpp231
-rw-r--r--tests/validation/NEON/ActivationLayer.cpp73
2 files changed, 285 insertions, 19 deletions
diff --git a/tests/validation/CL/ActivationLayer.cpp b/tests/validation/CL/ActivationLayer.cpp
new file mode 100644
index 0000000000..793ab30942
--- /dev/null
+++ b/tests/validation/CL/ActivationLayer.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 "PaddingCalculator.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/CL/CLTensor.h"
+#include "arm_compute/runtime/CL/CLTensorAllocator.h"
+#include "arm_compute/runtime/CL/functions/CLActivationLayer.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::cl;
+using namespace arm_compute::test::validation;
+
+namespace
+{
+/** 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..
+ *
+ * @return Tolerance depending on the activation function.
+ */
+float activation_layer_tolerance(ActivationLayerInfo::ActivationFunction activation, int fixed_point_position = 0)
+{
+ switch(activation)
+ {
+ case ActivationLayerInfo::ActivationFunction::LOGISTIC:
+ case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
+ case ActivationLayerInfo::ActivationFunction::SQRT:
+ case ActivationLayerInfo::ActivationFunction::TANH:
+ return (fixed_point_position != 0) ? 5.f : 0.00001f;
+ break;
+ default:
+ return 0.f;
+ }
+}
+
+/** Compute CL activation layer function.
+ *
+ * @param[in] in_place Compute the activation layer in-place.
+ * @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 (Optional) Number of bits for the fractional part of fixed point numbers.
+ *
+ * @return Computed output tensor.
+ */
+CLTensor compute_activation_layer(bool in_place, const TensorShape &shape, DataType dt, ActivationLayerInfo act_info, int fixed_point_position = 0)
+{
+ // Create tensors
+ CLTensor src = create_tensor(shape, dt, 1, fixed_point_position);
+ CLTensor dst = create_tensor(shape, dt, 1, fixed_point_position);
+
+ // Create and configure function
+ CLActivationLayer act_layer;
+
+ if(in_place)
+ {
+ act_layer.configure(&src, nullptr, act_info);
+ }
+ else
+ {
+ act_layer.configure(&src, &dst, act_info);
+ }
+
+ // Allocate tensors
+ src.allocator()->allocate();
+ BOOST_TEST(!src.info()->is_resizable());
+
+ if(!in_place)
+ {
+ dst.allocator()->allocate();
+ BOOST_TEST(!dst.info()->is_resizable());
+ }
+
+ // Fill tensors
+ 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(CLAccessor(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(CLAccessor(src), distribution, 0);
+ }
+
+ // Compute function
+ act_layer.run();
+
+ if(in_place)
+ {
+ return src;
+ }
+ else
+ {
+ return dst;
+ }
+}
+} // namespace
+
+#ifndef DOXYGEN_SKIP_THIS
+BOOST_AUTO_TEST_SUITE(CL)
+BOOST_AUTO_TEST_SUITE(ActivationLayer)
+
+BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
+BOOST_DATA_TEST_CASE(Configuration, boost::unit_test::data::make({ false, true }) * (SmallShapes() + LargeShapes()) * CNNFloatDataTypes(), in_place, shape, dt)
+{
+ // Set fixed point position data type allowed
+ const int fixed_point_position = (arm_compute::is_data_type_fixed_point(dt)) ? 3 : 0;
+
+ // Create tensors
+ CLTensor src = create_tensor(shape, dt, 1, fixed_point_position);
+ CLTensor 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
+ 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 PaddingSize padding = PaddingCalculator(shape.x(), 16).required_padding();
+ validate(src.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, boost::unit_test::data::make({ false, true }) * SmallShapes() * CNNFloatDataTypes() * ActivationFunctions(), in_place, shape, dt, act_function)
+{
+ // Create activation layer info
+ ActivationLayerInfo act_info(act_function, 1.f, 1.f);
+
+ // Compute function
+ CLTensor dst = compute_activation_layer(in_place, shape, dt, act_info);
+
+ // Compute reference
+ RawTensor ref_dst = Reference::compute_reference_activation_layer(shape, dt, act_info);
+
+ // Validate output
+ validate(CLAccessor(dst), ref_dst, activation_layer_tolerance(act_function));
+}
+
+BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
+BOOST_DATA_TEST_CASE(RunLarge, boost::unit_test::data::make({ false, true }) * LargeShapes() * CNNFloatDataTypes() * ActivationFunctions(), in_place, shape, dt, act_function)
+{
+ // Create activation layer info
+ ActivationLayerInfo act_info(act_function, 1.f, 1.f);
+
+ // Compute function
+ CLTensor dst = compute_activation_layer(in_place, shape, dt, act_info);
+
+ // Compute reference
+ RawTensor ref_dst = Reference::compute_reference_activation_layer(shape, dt, act_info);
+
+ // Validate output
+ validate(CLAccessor(dst), ref_dst, activation_layer_tolerance(act_function));
+}
+BOOST_AUTO_TEST_SUITE_END()
+
+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 a4826accfa..11ac6696b1 100644
--- a/tests/validation/NEON/ActivationLayer.cpp
+++ b/tests/validation/NEON/ActivationLayer.cpp
@@ -76,14 +76,15 @@ float activation_layer_tolerance(ActivationLayerInfo::ActivationFunction activat
/** Compute Neon activation layer function.
*
+ * @param[in] in_place Compute the activation layer in-place.
* @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.
+ * @param[in] fixed_point_position (Optional) 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)
+Tensor compute_activation_layer(bool in_place, const TensorShape &shape, DataType dt, ActivationLayerInfo act_info, int fixed_point_position = 0)
{
// Create tensors
Tensor src = create_tensor(shape, dt, 1, fixed_point_position);
@@ -91,14 +92,25 @@ Tensor compute_activation_layer(const TensorShape &shape, DataType dt, Activatio
// Create and configure function
NEActivationLayer act_layer;
- act_layer.configure(&src, &dst, act_info);
+
+ if(in_place)
+ {
+ act_layer.configure(&src, nullptr, act_info);
+ }
+ else
+ {
+ 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());
+
+ if(!in_place)
+ {
+ dst.allocator()->allocate();
+ BOOST_TEST(!dst.info()->is_resizable());
+ }
// Fill tensors
if(dt == DataType::F32)
@@ -121,7 +133,14 @@ Tensor compute_activation_layer(const TensorShape &shape, DataType dt, Activatio
// Compute function
act_layer.run();
- return dst;
+ if(in_place)
+ {
+ return src;
+ }
+ else
+ {
+ return dst;
+ }
}
} // namespace
@@ -130,10 +149,10 @@ 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)
+BOOST_DATA_TEST_CASE(Configuration, boost::unit_test::data::make({ false, true }) * (SmallShapes() + LargeShapes()) * CNNDataTypes(), in_place, shape, dt)
{
// 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 = (arm_compute::is_data_type_fixed_point(dt)) ? 3 : 0;
// Create tensors
Tensor src = create_tensor(shape, dt, 1, fixed_point_position);
@@ -144,28 +163,44 @@ BOOST_DATA_TEST_CASE(Configuration, (SmallShapes() + LargeShapes()) * CNNDataTyp
// Create and configure function
NEActivationLayer act_layer;
- act_layer.configure(&src, &dst, ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::ABS));
+
+ 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);
- validate(dst.info()->valid_region(), valid_region);
+
+ if(!in_place)
+ {
+ 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);
+
+ 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)
+BOOST_DATA_TEST_CASE(RunSmall, boost::unit_test::data::make({ false, true }) * SmallShapes() * CNNFloatDataTypes() * ActivationFunctions(), in_place, shape, dt, act_function)
{
// Create activation layer info
ActivationLayerInfo act_info(act_function, 1.f, 1.f);
// Compute function
- Tensor dst = compute_activation_layer(shape, dt, act_info);
+ Tensor dst = compute_activation_layer(in_place, shape, dt, act_info);
// Compute reference
RawTensor ref_dst = Reference::compute_reference_activation_layer(shape, dt, act_info);
@@ -175,13 +210,13 @@ BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * CNNFloatDataTypes() * ActivationF
}
BOOST_TEST_DECORATOR(*boost::unit_test::label("nightly"))
-BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * CNNFloatDataTypes() * ActivationFunctions(), shape, dt, act_function)
+BOOST_DATA_TEST_CASE(RunLarge, boost::unit_test::data::make({ false, true }) * LargeShapes() * CNNFloatDataTypes() * ActivationFunctions(), in_place, shape, dt, act_function)
{
// Create activation layer info
ActivationLayerInfo act_info(act_function, 1.f, 1.f);
// Compute function
- Tensor dst = compute_activation_layer(shape, dt, act_info);
+ Tensor dst = compute_activation_layer(in_place, shape, dt, act_info);
// Compute reference
RawTensor ref_dst = Reference::compute_reference_activation_layer(shape, dt, act_info);
@@ -196,14 +231,14 @@ BOOST_AUTO_TEST_SUITE_END()
*/
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)
+BOOST_DATA_TEST_CASE(RunSmall, boost::unit_test::data::make({ false, true }) * SmallShapes() * ActivationFunctions() * boost::unit_test::data::xrange(3, 6, 1),
+ in_place, shape, act_function, fixed_point_position)
{
// 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);
+ Tensor dst = compute_activation_layer(in_place, 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);