From d0ae8b8ac8a371fd552c46d4b3be3db8628a5ade Mon Sep 17 00:00:00 2001 From: Moritz Pflanzer Date: Thu, 29 Jun 2017 14:51:57 +0100 Subject: COMPMID-417: Extract common toolchain support file The support file is needed as Android toolchains are missing some C++11 functions. It further includes functions that have been introduced in C++14 but which we already need. Eventually the support file might become unnecessary if the Android compilers improve and we switch to C++14. Change-Id: Ib5ec506f1a17c78149c315ab2096b901b852c180 Reviewed-on: http://mpd-gerrit.cambridge.arm.com/79247 Reviewed-by: Georgios Pinitas Tested-by: Kaizen Reviewed-by: Pablo Tello --- tests/RawTensor.cpp | 7 +- tests/Utils.h | 277 +---------------------------------- tests/benchmark/PMUCounter.cpp | 3 +- tests/benchmark/WallClockTimer.cpp | 3 +- tests/benchmark/main.cpp | 5 +- tests/validation/FixedPoint.h | 3 +- tests/validation/TensorOperations.h | 9 +- tests/validation/UNIT/FixedPoint.cpp | 5 +- tests/validation/UNIT/Utils.cpp | 5 +- tests/validation/main.cpp | 5 +- 10 files changed, 31 insertions(+), 291 deletions(-) (limited to 'tests') diff --git a/tests/RawTensor.cpp b/tests/RawTensor.cpp index 6bfdf57b36..402b5f3d0b 100644 --- a/tests/RawTensor.cpp +++ b/tests/RawTensor.cpp @@ -26,6 +26,7 @@ #include "Utils.h" #include "arm_compute/core/Utils.h" +#include "support/ToolchainSupport.h" #include #include @@ -43,7 +44,7 @@ RawTensor::RawTensor(TensorShape shape, Format format, int fixed_point_position) _format(format), _fixed_point_position(fixed_point_position) { - _buffer = ::arm_compute::test::cpp14::make_unique(size()); + _buffer = support::cpp14::make_unique(size()); } RawTensor::RawTensor(TensorShape shape, DataType data_type, int num_channels, int fixed_point_position) @@ -53,7 +54,7 @@ RawTensor::RawTensor(TensorShape shape, DataType data_type, int num_channels, in _num_channels(num_channels), _fixed_point_position(fixed_point_position) { - _buffer = ::arm_compute::test::cpp14::make_unique(size()); + _buffer = support::cpp14::make_unique(size()); } RawTensor::RawTensor(const RawTensor &tensor) @@ -62,7 +63,7 @@ RawTensor::RawTensor(const RawTensor &tensor) _format(tensor.format()), _fixed_point_position(tensor.fixed_point_position()) { - _buffer = ::arm_compute::test::cpp14::make_unique(tensor.size()); + _buffer = support::cpp14::make_unique(tensor.size()); std::copy(tensor.data(), tensor.data() + size(), _buffer.get()); } diff --git a/tests/Utils.h b/tests/Utils.h index 25023d46e6..3be046182a 100644 --- a/tests/Utils.h +++ b/tests/Utils.h @@ -27,8 +27,10 @@ #include "arm_compute/core/Coordinates.h" #include "arm_compute/core/Error.h" #include "arm_compute/core/FixedPoint.h" +#include "arm_compute/core/TensorInfo.h" #include "arm_compute/core/TensorShape.h" #include "arm_compute/core/Types.h" +#include "support/ToolchainSupport.h" #include #include @@ -46,230 +48,6 @@ namespace arm_compute { namespace test { -namespace cpp11 -{ -#ifdef __ANDROID__ -/** Convert integer and float values to string. - * - * @note This function implements the same behaviour as std::to_string. The - * latter is missing in some Android toolchains. - * - * @param[in] value Value to be converted to string. - * - * @return String representation of @p value. - */ -template ::type>::value, int>::type = 0> -std::string to_string(T && value) -{ - std::stringstream stream; - stream << std::forward(value); - return stream.str(); -} - -/** Convert string values to integer. - * - * @note This function implements the same behaviour as std::stoi. The latter - * is missing in some Android toolchains. - * - * @param[in] str String to be converted to int. - * - * @return Integer representation of @p str. - */ -inline int stoi(const std::string &str) -{ - std::stringstream stream(str); - int value = 0; - stream >> value; - return value; -} - -/** Convert string values to unsigned long. - * - * @note This function implements the same behaviour as std::stoul. The latter - * is missing in some Android toolchains. - * - * @param[in] str String to be converted to unsigned long. - * - * @return Unsigned long representation of @p str. - */ -inline unsigned long stoul(const std::string &str) -{ - std::stringstream stream(str); - unsigned long value = 0; - stream >> value; - return value; -} - -/** Convert string values to float. - * - * @note This function implements the same behaviour as std::stof. The latter - * is missing in some Android toolchains. - * - * @param[in] str String to be converted to float. - * - * @return Float representation of @p str. - */ -inline float stof(const std::string &str) -{ - std::stringstream stream(str); - float value = 0.f; - stream >> value; - return value; -} - -/** Round floating-point value with half value rounding away from zero. - * - * @note This function implements the same behaviour as std::round except that it doesn't - * support Integral type. The latter is not in the namespace std in some Android toolchains. - * - * @param[in] value floating-point value to be rounded. - * - * @return Floating-point value of rounded @p value. - */ -template ::value>::type> -inline T round(T value) -{ - return ::round(value); -} - -/** Truncate floating-point value. - * - * @note This function implements the same behaviour as std::truncate except that it doesn't - * support Integral type. The latter is not in the namespace std in some Android toolchains. - * - * @param[in] value floating-point value to be truncated. - * - * @return Floating-point value of truncated @p value. - */ -template ::value>::type> -inline T trunc(T value) -{ - return ::trunc(value); -} - -/** Composes a floating point value with the magnitude of @p x and the sign of @p y. - * - * @note This function implements the same behaviour as std::copysign except that it doesn't - * support Integral type. The latter is not in the namespace std in some Android toolchains. - * - * @param[in] x value that contains the magnitued to be used in constructing the result. - * @param[in] y value that contains the sign to be used in constructin the result. - * - * @return Floating-point value with magnitude of @p x and sign of @p y. - */ -template ::value>::type> -inline T copysign(T x, T y) -{ - return ::copysign(x, y); -} -#else -/** Convert integer and float values to string. - * - * @note This function acts as a convenience wrapper around std::to_string. The - * latter is missing in some Android toolchains. - * - * @param[in] value Value to be converted to string. - * - * @return String representation of @p value. - */ -template -std::string to_string(T &&value) -{ - return ::std::to_string(std::forward(value)); -} - -/** Convert string values to integer. - * - * @note This function acts as a convenience wrapper around std::stoi. The - * latter is missing in some Android toolchains. - * - * @param[in] args Arguments forwarded to std::stoi. - * - * @return Integer representation of input string. - */ -template -int stoi(Ts &&... args) -{ - return ::std::stoi(std::forward(args)...); -} - -/** Convert string values to unsigned long. - * - * @note This function acts as a convenience wrapper around std::stoul. The - * latter is missing in some Android toolchains. - * - * @param[in] args Arguments forwarded to std::stoul. - * - * @return Unsigned long representation of input string. - */ -template -int stoul(Ts &&... args) -{ - return ::std::stoul(std::forward(args)...); -} - -/** Convert string values to float. - * - * @note This function acts as a convenience wrapper around std::stof. The - * latter is missing in some Android toolchains. - * - * @param[in] args Arguments forwarded to std::stof. - * - * @return Float representation of input string. - */ -template -int stof(Ts &&... args) -{ - return ::std::stof(std::forward(args)...); -} - -/** Round floating-point value with half value rounding away from zero. - * - * @note This function implements the same behaviour as std::round except that it doesn't - * support Integral type. The latter is not in the namespace std in some Android toolchains. - * - * @param[in] value floating-point value to be rounded. - * - * @return Floating-point value of rounded @p value. - */ -template ::value>::type> -inline T round(T value) -{ - return std::round(value); -} - -/** Truncate floating-point value. - * - * @note This function implements the same behaviour as std::truncate except that it doesn't - * support Integral type. The latter is not in the namespace std in some Android toolchains. - * - * @param[in] value floating-point value to be truncated. - * - * @return Floating-point value of truncated @p value. - */ -template ::value>::type> -inline T trunc(T value) -{ - return std::trunc(value); -} - -/** Composes a floating point value with the magnitude of @p x and the sign of @p y. - * - * @note This function implements the same behaviour as std::copysign except that it doesn't - * support Integral type. The latter is not in the namespace std in some Android toolchains. - * - * @param[in] x value that contains the magnitued to be used in constructing the result. - * @param[in] y value that contains the sign to be used in constructin the result. - * - * @return Floating-point value with magnitude of @p x and sign of @p y. - */ -template ::value>::type> -inline T copysign(T x, T y) -{ - return std::copysign(x, y); -} -#endif - /** Round floating-point value with half value rounding to positive infinity. * * @param[in] value floating-point value to be rounded. @@ -301,58 +79,14 @@ inline T round_half_even(T value, T epsilon = std::numeric_limits::epsilon()) // If 'ipart' is even then return 'ipart' if(std::fmod(ipart, 2.f) < epsilon) { - return cpp11::copysign(ipart, value); + return support::cpp11::copysign(ipart, value); } // Else return the nearest even integer - return cpp11::copysign(std::ceil(ipart + 0.5f), value); + return support::cpp11::copysign(std::ceil(ipart + 0.5f), value); } // Otherwise use the usual round to closest - return cpp11::copysign(cpp11::round(positive_value), value); + return support::cpp11::copysign(support::cpp11::round(positive_value), value); } -} // namespace cpp11 - -namespace cpp14 -{ -/** make_unqiue is missing in CPP11. Reimplement it according to the standard - * proposal. - */ -template -struct _Unique_if -{ - typedef std::unique_ptr _Single_object; -}; - -template -struct _Unique_if -{ - typedef std::unique_ptr _Unknown_bound; -}; - -template -struct _Unique_if -{ - typedef void _Known_bound; -}; - -template -typename _Unique_if::_Single_object -make_unique(Args &&... args) -{ - return std::unique_ptr(new T(std::forward(args)...)); -} - -template -typename _Unique_if::_Unknown_bound -make_unique(size_t n) -{ - typedef typename std::remove_extent::type U; - return std::unique_ptr(new U[n]()); -} - -template -typename _Unique_if::_Known_bound -make_unique(Args &&...) = delete; -} // namespace cpp14 namespace traits { @@ -663,7 +397,6 @@ inline bool is_in_valid_region(const ValidRegion &valid_region, const Coordinate } return true; } - } // namespace test } // namespace arm_compute #endif diff --git a/tests/benchmark/PMUCounter.cpp b/tests/benchmark/PMUCounter.cpp index e87dae82e6..6d59dae65d 100644 --- a/tests/benchmark/PMUCounter.cpp +++ b/tests/benchmark/PMUCounter.cpp @@ -24,6 +24,7 @@ #include "PMUCounter.h" #include "Utils.h" +#include "support/ToolchainSupport.h" #define _GNU_SOURCE 1 #include @@ -89,7 +90,7 @@ void CycleCounter::stop() std::unique_ptr CycleCounter::get_measurement() const { - return ::arm_compute::test::cpp14::make_unique>(_cycles); + return support::cpp14::make_unique>(_cycles); } InstructionCounter::InstructionCounter() diff --git a/tests/benchmark/WallClockTimer.cpp b/tests/benchmark/WallClockTimer.cpp index 9ab53d0b3c..717fe04b31 100644 --- a/tests/benchmark/WallClockTimer.cpp +++ b/tests/benchmark/WallClockTimer.cpp @@ -24,6 +24,7 @@ #include "WallClockTimer.h" #include "Utils.h" +#include "support/ToolchainSupport.h" namespace arm_compute { @@ -49,7 +50,7 @@ void WallClockTimer::stop() std::unique_ptr WallClockTimer::get_measurement() const { const std::chrono::duration delta = _stop - _start; - return ::arm_compute::test::cpp14::make_unique>(delta.count()); + return support::cpp14::make_unique>(delta.count()); } } // namespace benchmark } // namespace test diff --git a/tests/benchmark/main.cpp b/tests/benchmark/main.cpp index 7ce6a26acd..1b6bafb3a1 100644 --- a/tests/benchmark/main.cpp +++ b/tests/benchmark/main.cpp @@ -30,6 +30,7 @@ #include "WallClockTimer.h" #include "benchmark/benchmark_api.h" +#include "support/ToolchainSupport.h" #ifdef OPENCL #include "arm_compute/runtime/CL/CLScheduler.h" @@ -78,11 +79,11 @@ int main(int argc, char **argv) if(user_config.seed.is_set()) { - library = cpp14::make_unique(user_config.path.get(), user_config.seed); + library = arm_compute::support::cpp14::make_unique(user_config.path.get(), user_config.seed); } else { - library = cpp14::make_unique(user_config.path.get()); + library = arm_compute::support::cpp14::make_unique(user_config.path.get()); } #ifdef OPENCL diff --git a/tests/validation/FixedPoint.h b/tests/validation/FixedPoint.h index fa99ff84c2..dca6e7ed2f 100644 --- a/tests/validation/FixedPoint.h +++ b/tests/validation/FixedPoint.h @@ -25,6 +25,7 @@ #define __ARM_COMPUTE_TEST_VALIDATION_FIXEDPOINT_H__ #include "Utils.h" +#include "support/ToolchainSupport.h" #include #include @@ -147,7 +148,7 @@ public: * @param[in] p Fixed point precision */ fixed_point(std::string str, uint8_t p) - : _value(detail::constant_expr::to_fixed(arm_compute::test::cpp11::stof(str), p)), _fixed_point_position(p) + : _value(detail::constant_expr::to_fixed(support::cpp11::stof(str), p)), _fixed_point_position(p) { assert(p > 0 && p < std::numeric_limits::digits); } diff --git a/tests/validation/TensorOperations.h b/tests/validation/TensorOperations.h index 5557cfc2df..4f7765613c 100644 --- a/tests/validation/TensorOperations.h +++ b/tests/validation/TensorOperations.h @@ -28,6 +28,7 @@ #include "Tensor.h" #include "Types.h" #include "Utils.h" +#include "support/ToolchainSupport.h" #include "FixedPoint.h" #include "Types.h" @@ -257,7 +258,7 @@ void apply_2d_spatial_filter(Coordinates coord, const Tensor &in, Tensor } coord.set(0, x); coord.set(1, y); - const double rounded_val = cpp11::trunc(val * static_cast(scale)); + const double rounded_val = support::cpp11::trunc(val * static_cast(scale)); out[coord2index(in.shape(), coord)] = saturate_cast(rounded_val); } } // namespace @@ -790,13 +791,13 @@ void pixel_wise_multiplication(const Tensor &in1, const Tensor &in2, Ten switch(rounding_policy) { case(RoundingPolicy::TO_ZERO): - rounded_val = cpp11::trunc(val); + rounded_val = support::cpp11::trunc(val); break; case(RoundingPolicy::TO_NEAREST_UP): - rounded_val = cpp11::round_half_up(val); + rounded_val = round_half_up(val); break; case(RoundingPolicy::TO_NEAREST_EVEN): - rounded_val = cpp11::round_half_even(val); + rounded_val = round_half_even(val); break; default: ARM_COMPUTE_ERROR("Unsupported rounding policy"); diff --git a/tests/validation/UNIT/FixedPoint.cpp b/tests/validation/UNIT/FixedPoint.cpp index 8042bb6da8..9206863ec6 100644 --- a/tests/validation/UNIT/FixedPoint.cpp +++ b/tests/validation/UNIT/FixedPoint.cpp @@ -25,6 +25,7 @@ #include "TypePrinter.h" #include "Utils.h" +#include "support/ToolchainSupport.h" #include "validation/Validation.h" #include "validation/ValidationUserConfiguration.h" @@ -52,7 +53,7 @@ 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); + const std::string base_file_name = user_config.path.get() + "/dumps/" + func_name + "_Q8." + support::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"); @@ -84,7 +85,7 @@ BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::l 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); + const std::string base_file_name = user_config.path.get() + "/dumps/" + func_name + "_Q8." + support::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 }; diff --git a/tests/validation/UNIT/Utils.cpp b/tests/validation/UNIT/Utils.cpp index 7a09be52b5..69523a5620 100644 --- a/tests/validation/UNIT/Utils.cpp +++ b/tests/validation/UNIT/Utils.cpp @@ -32,7 +32,6 @@ 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 @@ -43,14 +42,14 @@ BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::l 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(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(round_half_even(value) == result); } BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly")) diff --git a/tests/validation/main.cpp b/tests/validation/main.cpp index c89372637f..6ec6885159 100644 --- a/tests/validation/main.cpp +++ b/tests/validation/main.cpp @@ -28,6 +28,7 @@ #include "Utils.h" #include "ValidationProgramOptions.h" #include "ValidationUserConfiguration.h" +#include "support/ToolchainSupport.h" #include "arm_compute/runtime/Scheduler.h" @@ -55,11 +56,11 @@ struct GlobalFixture { if(user_config.seed.is_set()) { - library = cpp14::make_unique(user_config.path.get(), user_config.seed); + library = arm_compute::support::cpp14::make_unique(user_config.path.get(), user_config.seed); } else { - library = cpp14::make_unique(user_config.path.get()); + library = arm_compute::support::cpp14::make_unique(user_config.path.get()); } std::cout << "Seed: " << library->seed() << "\n"; -- cgit v1.2.1