diff options
Diffstat (limited to 'tests/framework')
-rw-r--r-- | tests/framework/Utils.h | 16 | ||||
-rw-r--r-- | tests/framework/instruments/MaliCounter.cpp | 12 | ||||
-rw-r--r-- | tests/framework/instruments/MaliCounter.h | 2 | ||||
-rw-r--r-- | tests/framework/instruments/Measurement.h | 223 | ||||
-rw-r--r-- | tests/framework/printers/JSONPrinter.cpp | 33 | ||||
-rw-r--r-- | tests/framework/printers/PrettyPrinter.cpp | 26 |
6 files changed, 241 insertions, 71 deletions
diff --git a/tests/framework/Utils.h b/tests/framework/Utils.h index a9fe0dcaa3..4f4b6fce56 100644 --- a/tests/framework/Utils.h +++ b/tests/framework/Utils.h @@ -152,6 +152,22 @@ inline std::string tolower(std::string string) }); return string; } + +/** Create a string with the arithmetic value in full precision. + * + * @param val Arithmetic value + * + * @return String with the arithmetic value. + */ +template <typename T, typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0> +inline std::string arithmetic_to_string(T val) +{ + std::stringstream ss; + ss.precision(std::numeric_limits<T>::digits10 + 1); + ss << val; + return ss.str(); +} + } // namespace framework } // namespace test } // namespace arm_compute diff --git a/tests/framework/instruments/MaliCounter.cpp b/tests/framework/instruments/MaliCounter.cpp index 6cc3ac5bcb..f36d1801a3 100644 --- a/tests/framework/instruments/MaliCounter.cpp +++ b/tests/framework/instruments/MaliCounter.cpp @@ -111,7 +111,7 @@ MaliCounter::MaliCounter() { _counters = { - { "GPU_ACTIVE", TypedMeasurement<uint64_t>(0, "cycles") }, + { "GPU_ACTIVE", Measurement(0, "cycles") }, }; _core_counters = @@ -373,8 +373,8 @@ void MaliCounter::stop() sample_counters(); wait_next_event(); - const auto counter = get_counters(mali_userspace::MALI_NAME_BLOCK_JM); - _counters.at("GPU_ACTIVE").value = counter[find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_JM, "GPU_ACTIVE")]; + const uint32_t *counter = get_counters(mali_userspace::MALI_NAME_BLOCK_JM); + _counters.at("GPU_ACTIVE") = Measurement(counter[find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_JM, "GPU_ACTIVE")], _counters.at("GPU_ACTIVE").unit()); const int arith_index = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "ARITH_WORDS"); const int ls_index = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "LS_ISSUE"); @@ -385,7 +385,7 @@ void MaliCounter::stop() // Shader core counters can be averaged if desired, but here we don't. for(int core = 0; core < _num_cores; ++core) { - const auto sc_counter = get_counters(mali_userspace::MALI_NAME_BLOCK_SHADER, core); + const uint32_t *sc_counter = get_counters(mali_userspace::MALI_NAME_BLOCK_SHADER, core); _core_counters.at("ARITH_WORDS").values[core] = sc_counter[arith_index]; _core_counters.at("LS_ISSUE").values[core] = sc_counter[ls_index]; @@ -406,7 +406,7 @@ Instrument::MeasurementsMap MaliCounter::measurements() const { MeasurementsMap measurements { - { "Timespan", TypedMeasurement<uint64_t>(_stop_time - _start_time, "ns") }, + { "Timespan", Measurement(_stop_time - _start_time, "ns") }, { "GPU active", _counters.at("GPU_ACTIVE") }, }; @@ -414,7 +414,7 @@ Instrument::MeasurementsMap MaliCounter::measurements() const { for(const auto &core : counter.second.values) { - measurements.emplace(counter.second.name + " #" + support::cpp11::to_string(core.first), TypedMeasurement<uint64_t>(core.second, counter.second.unit)); + measurements.emplace(counter.second.name + " #" + support::cpp11::to_string(core.first), Measurement(core.second, counter.second.unit)); } } diff --git a/tests/framework/instruments/MaliCounter.h b/tests/framework/instruments/MaliCounter.h index c7aaa3c4fd..64b5b93015 100644 --- a/tests/framework/instruments/MaliCounter.h +++ b/tests/framework/instruments/MaliCounter.h @@ -65,7 +65,7 @@ private: const uint32_t *get_counters(mali_userspace::MaliCounterBlockName block, int core = -1) const; int find_counter_index_by_name(mali_userspace::MaliCounterBlockName block, const char *name); - std::map<std::string, TypedMeasurement<uint64_t>> _counters{}; + std::map<std::string, Measurement> _counters{}; struct core_counters { diff --git a/tests/framework/instruments/Measurement.h b/tests/framework/instruments/Measurement.h index 324fd51b47..08624f3345 100644 --- a/tests/framework/instruments/Measurement.h +++ b/tests/framework/instruments/Measurement.h @@ -25,7 +25,9 @@ #define ARM_COMPUTE_TEST_MEASUREMENT #include "../Utils.h" +#include "arm_compute/core/Error.h" +#include <list> #include <ostream> #include <string> @@ -35,67 +37,204 @@ namespace test { namespace framework { -/** Abstract measurement. - * - * Every measurement needs to define it's unit. - */ -struct IMeasurement +/** Generic measurement that stores values as either double or long long int. */ +struct Measurement { - /** Constructor. + struct Value + { + /** Constructor + * + * @param[in] is_floating Will the value stored be floating point ? + */ + Value(bool is_floating) + : v{ 0 }, is_floating_point(is_floating) + { + } + + /** Add the value stored to the stream as a string + */ + friend std::ostream &operator<<(std::ostream &os, const Value &value) + { + if(value.is_floating_point) + { + os << arithmetic_to_string(value.v.floating_point); + } + else + { + os << arithmetic_to_string(value.v.integer); + } + return os; + } + /** Convert the value stored to string + */ + std::string to_string() const + { + std::stringstream ss; + ss << *this; + return ss.str(); + } + /** Add with another value and return the sum + * + * @param[in] b Other value + * + * @return Sum of the stored value + b + */ + Value operator+(Value b) const + { + if(is_floating_point) + { + b.v.floating_point += v.floating_point; + } + else + { + b.v.integer += v.integer; + } + return b; + } + + /** Return the stored value divided by an integer. + * + * @param[in] b Integer to divide the value by. + * + * @return Stored value / b + */ + Value operator/(int b) const + { + Value res(is_floating_point); + if(is_floating_point) + { + res.v.floating_point = v.floating_point / b; + } + else + { + res.v.integer = v.integer / b; + } + return res; + } + + /** Subtract another value and return the updated stored value. + * + * @param[in] b Other value + * + * @return The updated stored value + */ + Value &operator-=(const Value &b) + { + if(is_floating_point) + { + v.floating_point -= b.v.floating_point; + } + else + { + v.integer -= b.v.integer; + } + return *this; + } + + /** Compare the stored value with another value + * + * @param[in] b Value to compare against + * + * @return The result of stored value < b + */ + bool operator<(const Value &b) const + { + if(is_floating_point) + { + return v.floating_point < b.v.floating_point; + } + else + { + return v.integer < b.v.integer; + } + } + + /** Stored value */ + union + { + double floating_point; + long long int integer; + } v; + bool is_floating_point; /**< Is the stored value floating point or integer ? */ + }; + + /** Stream output operator to print the measurement. * - * @param[in] unit Unit of the measurement. + * Prints value and unit. */ - explicit IMeasurement(std::string unit) - : unit{ std::move(unit) } + friend inline std::ostream &operator<<(std::ostream &os, const Measurement &measurement) { + os << measurement._value << " " << measurement._unit; + return os; } - std::string unit; -}; - -/** Measurement of a specific type. */ -template <typename T> -struct TypedMeasurement : public IMeasurement -{ - /** Constructor. + /** Constructor to store a floating point value * - * @param[in] value Measured value. - * @param[in] unit Unit of the Measurement. + * @param[in] v Value to store + * @param[in] unit Unit of @p v + * @param[in] raw (Optional) The raw value(s) @p was generated from. */ - TypedMeasurement(T value, std::string unit) - : IMeasurement(std::move(unit)), value{ value } + template < typename Floating, typename std::enable_if < !std::is_integral<Floating>::value, int >::type = 0 > + Measurement(Floating v, std::string unit, std::list<std::string> raw = {}) + : _unit(unit), _raw_data(std::move(raw)), _value(true) { + _value.v.floating_point = static_cast<double>(v); + if(_raw_data.empty()) + { + _raw_data = { _value.to_string() }; + } } - T value; -}; + /** Constructor to store an integer value + * + * @param[in] v Value to store + * @param[in] unit Unit of @p v + * @param[in] raw (Optional) The raw value(s) @p was generated from. + */ + template <typename Integer, typename std::enable_if<std::is_integral<Integer>::value, int>::type = 0> + Measurement(Integer v, std::string unit, std::list<std::string> raw = {}) + : _unit(unit), _raw_data(std::move(raw)), _value(false) + { + _value.v.integer = static_cast<long long int>(v); + if(_raw_data.empty()) + { + _raw_data = { _value.to_string() }; + } + } -/** Stream output operator to print the measurement. - * - * Prints value and unit. - */ -template <typename T> -inline std::ostream &operator<<(std::ostream &os, const TypedMeasurement<T> &measurement) -{ - os << measurement.value << measurement.unit; - return os; -} + /** Accessor for the unit of the measurement + * + * @return Unit of the measurement + */ + const std::string &unit() const + { + return _unit; + } -/** Generic measurement that stores values as double. */ -struct Measurement : public TypedMeasurement<double> -{ - using TypedMeasurement::TypedMeasurement; + /** Accessor for the raw data + * + * @return The raw data + */ + const std::list<std::string> &raw_data() const + { + return _raw_data; + } - /** Conversion constructor. + /** Accessor for the stored value * - * @param[in] measurement Typed measurement. + * @return The stored value */ - template <typename T> - Measurement(TypedMeasurement<T> measurement) - : Measurement(measurement.value, measurement.unit) + const Value &value() const { + return _value; } + +private: + std::string _unit; + std::list<std::string> _raw_data; + Value _value; }; + } // namespace framework } // namespace test } // namespace arm_compute diff --git a/tests/framework/printers/JSONPrinter.cpp b/tests/framework/printers/JSONPrinter.cpp index 4f17e6277b..bb85a134f2 100644 --- a/tests/framework/printers/JSONPrinter.cpp +++ b/tests/framework/printers/JSONPrinter.cpp @@ -164,36 +164,49 @@ void JSONPrinter::print_measurements(const Profiler::MeasurementsMap &measuremen { *_stream << R"(")" << i_it->first << R"(" : {)"; - auto add_measurements = [](double a, const Measurement & b) + auto add_measurements = [](Measurement::Value a, const Measurement & b) { - return a + b.value; + return a + b.value(); }; auto cmp_measurements = [](const Measurement & a, const Measurement & b) { - return a.value < b.value; + return a.value() < b.value(); }; - double sum_values = std::accumulate(i_it->second.cbegin(), i_it->second.cend(), 0., add_measurements); int num_values = i_it->second.size(); const auto minmax_values = std::minmax_element(i_it->second.begin(), i_it->second.end(), cmp_measurements); + Measurement::Value sum_values = std::accumulate(i_it->second.cbegin(), i_it->second.cend(), Measurement::Value(minmax_values.first->value().is_floating_point), add_measurements); if(num_values > 2) { - sum_values -= minmax_values.first->value + minmax_values.second->value; + sum_values -= minmax_values.first->value() + minmax_values.second->value(); num_values -= 2; } auto measurement_to_string = [](const Measurement & measurement) { - return support::cpp11::to_string(measurement.value); + if(measurement.raw_data().size() == 1) + { + return measurement.raw_data().front(); + } + else + { + std::stringstream str; + str << "["; + str << join(measurement.raw_data().begin(), measurement.raw_data().end(), ","); + str << "]"; + return str.str(); + } }; - *_stream << R"("avg" : )" << (sum_values / num_values) << ","; - *_stream << R"("min" : )" << minmax_values.first->value << ","; - *_stream << R"("max" : )" << minmax_values.second->value << ","; + if(num_values > 1) + { + *_stream << R"("min" : )" << minmax_values.first->value() << ","; + *_stream << R"("max" : )" << minmax_values.second->value() << ","; + } *_stream << R"("raw" : [)" << join(i_it->second.begin(), i_it->second.end(), ",", measurement_to_string) << "],"; - *_stream << R"("unit" : ")" << minmax_values.first->unit << R"(")"; + *_stream << R"("unit" : ")" << minmax_values.first->unit() << R"(")"; *_stream << "}"; if(++i_it != i_end) diff --git a/tests/framework/printers/PrettyPrinter.cpp b/tests/framework/printers/PrettyPrinter.cpp index 5eec72a2fe..280813f044 100644 --- a/tests/framework/printers/PrettyPrinter.cpp +++ b/tests/framework/printers/PrettyPrinter.cpp @@ -114,32 +114,34 @@ void PrettyPrinter::print_measurements(const Profiler::MeasurementsMap &measurem { *_stream << begin_color("3") << " " << instrument.first << ":"; - auto add_measurements = [](double a, const Measurement & b) + auto add_measurements = [](Measurement::Value a, const Measurement & b) { - return a + b.value; + return a + b.value(); }; auto cmp_measurements = [](const Measurement & a, const Measurement & b) { - return a.value < b.value; + return a.value() < b.value(); }; - double sum_values = std::accumulate(instrument.second.begin(), instrument.second.end(), 0., add_measurements); - int num_values = instrument.second.size(); - const auto minmax_values = std::minmax_element(instrument.second.begin(), instrument.second.end(), cmp_measurements); + int num_values = instrument.second.size(); + const auto minmax_values = std::minmax_element(instrument.second.begin(), instrument.second.end(), cmp_measurements); + Measurement::Value sum_values = std::accumulate(instrument.second.begin(), instrument.second.end(), Measurement::Value(minmax_values.first->value().is_floating_point), add_measurements); if(num_values > 2) { - sum_values -= minmax_values.first->value + minmax_values.second->value; + sum_values -= minmax_values.first->value() + minmax_values.second->value(); num_values -= 2; } - Measurement avg{ sum_values / num_values, minmax_values.first->unit }; - *_stream << " "; - *_stream << "AVG=" << avg << ", "; - *_stream << "MIN=" << *minmax_values.first << ", "; - *_stream << "MAX=" << *minmax_values.second << end_color() << "\n"; + *_stream << "AVG=" << (sum_values / num_values) << " " << minmax_values.second->unit() << ","; + if(num_values > 1) + { + *_stream << "MIN=" << *minmax_values.first << ", "; + *_stream << "MAX=" << *minmax_values.second; + } + *_stream << end_color() << "\n"; } } } // namespace framework |