aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2017-07-04 12:47:17 +0100
committerAnthony Barbier <anthony.barbier@arm.com>2018-09-17 14:15:39 +0100
commit21efeb4491feab09dc246f4da0023d7ca79b1d32 (patch)
tree2fbacd7676d13a3ec7024e517acf2e462355275a /tests
parent368da83fdd7406d629e8cca64f3eb0af05437419 (diff)
downloadComputeLibrary-21efeb4491feab09dc246f4da0023d7ca79b1d32.tar.gz
COMPMID-417: DepthConvert NEON for QS8/QS16.
Change-Id: Ieb120bccf146045b3a0001ceb3893d4e67fd19df Reviewed-on: http://mpd-gerrit.cambridge.arm.com/79763 Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com> Reviewed-by: Steven Niu <steven.niu@arm.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/TensorLibrary.h1
-rw-r--r--tests/validation/FixedPoint.h2
-rw-r--r--tests/validation/NEON/DepthConvert.cpp83
-rw-r--r--tests/validation/TensorOperations.h90
4 files changed, 112 insertions, 64 deletions
diff --git a/tests/TensorLibrary.h b/tests/TensorLibrary.h
index 5b2c5b6fd5..3fb593c886 100644
--- a/tests/TensorLibrary.h
+++ b/tests/TensorLibrary.h
@@ -560,6 +560,7 @@ void TensorLibrary::fill_tensor_uniform(T &&tensor, std::random_device::result_t
break;
}
case DataType::S16:
+ case DataType::QS16:
{
ARM_COMPUTE_ERROR_ON(!(std::is_same<int16_t, D>::value));
std::uniform_int_distribution<int16_t> distribution_s16(low, high);
diff --git a/tests/validation/FixedPoint.h b/tests/validation/FixedPoint.h
index 53f532cd8c..261fcd6df6 100644
--- a/tests/validation/FixedPoint.h
+++ b/tests/validation/FixedPoint.h
@@ -333,7 +333,7 @@ struct constant_expr
*/
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
*
diff --git a/tests/validation/NEON/DepthConvert.cpp b/tests/validation/NEON/DepthConvert.cpp
index 4a37d98990..65d3ab1be7 100644
--- a/tests/validation/NEON/DepthConvert.cpp
+++ b/tests/validation/NEON/DepthConvert.cpp
@@ -208,6 +208,89 @@ BOOST_DATA_TEST_CASE(RunLarge, LargeShapes() * boost::unit_test::data::make({ Co
}
BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE(QS16_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, 15, 1),
+ shape, policy, fixed_point_position)
+{
+ // Compute configure and validate region/padding
+ compute_configure_validate(shape, DataType::QS16, 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, 15, 1),
+ shape, policy, fixed_point_position)
+{
+ // Compute function
+ Tensor dst = compute_depth_convert(shape, DataType::QS16, DataType::F32, policy, 0, fixed_point_position);
+
+ // Compute reference
+ RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::QS16, DataType::F32, policy, 0, fixed_point_position);
+
+ // 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 })
+ * boost::unit_test::data::xrange(1, 15, 1),
+ shape, policy, fixed_point_position)
+{
+ // Compute function
+ Tensor dst = compute_depth_convert(shape, DataType::QS16, DataType::F32, policy, 0, fixed_point_position);
+
+ // Compute reference
+ RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::QS16, DataType::F32, policy, 0, fixed_point_position);
+
+ // Validate output
+ validate(NEAccessor(dst), ref_dst);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+BOOST_AUTO_TEST_SUITE(F32_to_QS16)
+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)
+{
+ // Compute configure and validate region/padding
+ compute_configure_validate(shape, DataType::F32, DataType::QS16, 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, 15, 1),
+ shape, policy, fixed_point_position)
+{
+ // Compute function
+ Tensor dst = compute_depth_convert(shape, DataType::F32, DataType::QS16, policy, 0, fixed_point_position);
+
+ // Compute reference
+ RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::F32, DataType::QS16, policy, 0, fixed_point_position);
+
+ // 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 })
+ * boost::unit_test::data::xrange(1, 15, 1),
+ shape, policy, fixed_point_position)
+{
+ // Compute function
+ Tensor dst = compute_depth_convert(shape, DataType::F32, DataType::QS16, policy, 0, fixed_point_position);
+
+ // Compute reference
+ RawTensor ref_dst = Reference::compute_reference_depth_convert(shape, DataType::F32, DataType::QS16, policy, 0, fixed_point_position);
+
+ // Validate output
+ validate(NEAccessor(dst), ref_dst);
+}
+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"))
diff --git a/tests/validation/TensorOperations.h b/tests/validation/TensorOperations.h
index 0502f53186..e90635f0d4 100644
--- a/tests/validation/TensorOperations.h
+++ b/tests/validation/TensorOperations.h
@@ -518,94 +518,58 @@ void box3x3(const Tensor<T> &in, Tensor<T> &out, BorderMode border_mode, T const
}
// Depth conversion
-template <typename T1, typename T2>
+template < typename T1, typename T2, typename std::enable_if < std::is_integral<T1>::value &&std::is_floating_point<T2>::value, int >::type = 0 >
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));
- }
-}
+ using namespace fixed_point_arithmetic;
-template <>
-void depth_convert<uint8_t, uint16_t>(const Tensor<uint8_t> &in, Tensor<uint16_t> &out, ConvertPolicy policy, uint32_t shift)
-{
+ const int fixed_point_position = in.fixed_point_position();
for(int i = 0; i < in.num_elements(); ++i)
{
- out[i] = static_cast<uint16_t>(in[i]) << shift;
+ out[i] = static_cast<float>(fixed_point<T1>(in[i], fixed_point_position, true));
}
}
-template <>
-void depth_convert<uint8_t, int16_t>(const Tensor<uint8_t> &in, Tensor<int16_t> &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 >
+void depth_convert(const Tensor<T1> &in, Tensor<T2> &out, ConvertPolicy policy, uint32_t shift)
{
- for(int i = 0; i < in.num_elements(); ++i)
- {
- out[i] = static_cast<int16_t>(in[i]) << shift;
- }
-}
+ using namespace fixed_point_arithmetic;
-template <>
-void depth_convert<uint8_t, int32_t>(const Tensor<uint8_t> &in, Tensor<int32_t> &out, ConvertPolicy policy, uint32_t shift)
-{
+ const int fixed_point_position = out.fixed_point_position();
for(int i = 0; i < in.num_elements(); ++i)
{
- out[i] = static_cast<int32_t>(in[i]) << shift;
+ out[i] = fixed_point<T2>(in[i], fixed_point_position).raw();
}
}
-template <>
-void depth_convert<uint16_t, uint8_t>(const Tensor<uint16_t> &in, Tensor<uint8_t> &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, int >::type = 0 >
+void depth_convert(const Tensor<T1> &in, Tensor<T2> &out, ConvertPolicy policy, uint32_t shift)
{
- for(int i = 0; i < in.num_elements(); ++i)
+ // Up-casting
+ if(std::numeric_limits<T1>::digits <= std::numeric_limits<T2>::digits)
{
- uint16_t val = in[i] >> shift;
- out[i] = ((policy == ConvertPolicy::SATURATE) ? saturate_cast<uint8_t>(val) : static_cast<uint8_t>(val));
+ for(int i = 0; i < in.num_elements(); ++i)
+ {
+ out[i] = static_cast<T2>(in[i]) << shift;
+ }
}
-}
-
-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)
+ // Down-casting
+ else
{
- out[i] = static_cast<uint32_t>(in[i]) << shift;
+ for(int i = 0; i < in.num_elements(); ++i)
+ {
+ T1 val = in[i] >> shift;
+ out[i] = ((policy == ConvertPolicy::SATURATE) ? saturate_cast<T2>(val) : static_cast<T2>(val));
+ }
}
}
-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)
+template < typename T1, typename T2, typename std::enable_if < std::is_floating_point<T1>::value &&std::is_floating_point<T2>::value, int >::type = 0 >
+void depth_convert(const Tensor<T1> &in, Tensor<T2> &out, ConvertPolicy policy, uint32_t shift)
{
for(int i = 0; i < in.num_elements(); ++i)
{
- out[i] = static_cast<int32_t>(in[i]) << shift;
+ out[i] = static_cast<T2>(in[i]);
}
}