diff options
Diffstat (limited to 'tests/validation')
-rw-r--r-- | tests/validation/FixedPoint.h | 2 | ||||
-rw-r--r-- | tests/validation/NEON/DepthConvert.cpp | 83 | ||||
-rw-r--r-- | tests/validation/TensorOperations.h | 90 |
3 files changed, 111 insertions, 64 deletions
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]); } } |