From c9afce52fe412e6f09917345b198a1f497571e8d Mon Sep 17 00:00:00 2001 From: Anthony Barbier Date: Fri, 26 Jan 2018 16:07:50 +0000 Subject: COMPMID-863: Remove some of the post-processing from the JSON backend Refactored the console printer too (So that we can re-use the code if needed) Change-Id: I16a0f70104f82f07cd59900b383038fa5a76e1bc Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/117858 Tested-by: Jenkins Reviewed-by: Pablo Tello --- scripts/fix_code_formatting.sh | 39 ----------- tests/framework/instruments/Instrument.h | 3 +- tests/framework/instruments/InstrumentsStats.cpp | 70 +++++++++++++++++++ tests/framework/instruments/InstrumentsStats.h | 89 ++++++++++++++++++++++++ tests/framework/printers/JSONPrinter.cpp | 30 +------- tests/framework/printers/PrettyPrinter.cpp | 51 +++----------- 6 files changed, 172 insertions(+), 110 deletions(-) delete mode 100755 scripts/fix_code_formatting.sh create mode 100644 tests/framework/instruments/InstrumentsStats.cpp create mode 100644 tests/framework/instruments/InstrumentsStats.h diff --git a/scripts/fix_code_formatting.sh b/scripts/fix_code_formatting.sh deleted file mode 100755 index 021f92516f..0000000000 --- a/scripts/fix_code_formatting.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -#FIXME: Remove this file before the release - -ASTYLE_PARAMETERS=" --style=ansi \ - --indent=spaces \ - --indent-switches \ - --indent-col1-comments \ - --min-conditional-indent=0 \ - --max-instatement-indent=120 \ - --pad-oper \ - --align-pointer=name \ - --align-reference=name \ - --break-closing-brackets \ - --keep-one-line-statements \ - --max-code-length=200 \ - --mode=c \ - --lineend=linux \ - --indent-preprocessor \ - " - -DIRECTORIES="./arm_compute ./src ./examples ./tests ./utils ./support" - -if [ $# -eq 0 ] -then - files=$(find $DIRECTORIES -type f \( -name \*.cpp -o -iname \*.h -o -name \*.inl -o -name \*.cl -o -name \*.cs \)) -else - files=$@ -fi -for f in $files -do - if [[ $f == *"/assembly/"* ]] - then - continue - fi - - sed -i 's/\t/ /g' $f - clang-format -i -style=file $f - astyle -n -q $ASTYLE_PARAMETERS $f -done diff --git a/tests/framework/instruments/Instrument.h b/tests/framework/instruments/Instrument.h index 9156d70010..e25939a284 100644 --- a/tests/framework/instruments/Instrument.h +++ b/tests/framework/instruments/Instrument.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -88,6 +88,7 @@ inline std::unique_ptr Instrument::make_instrument() { return support::cpp14::make_unique(scale); } + } // namespace framework } // namespace test } // namespace arm_compute diff --git a/tests/framework/instruments/InstrumentsStats.cpp b/tests/framework/instruments/InstrumentsStats.cpp new file mode 100644 index 0000000000..2b05e45aad --- /dev/null +++ b/tests/framework/instruments/InstrumentsStats.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018 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 "InstrumentsStats.h" + +namespace arm_compute +{ +namespace test +{ +namespace framework +{ +InstrumentsStats::InstrumentsStats(const std::vector &measurements) + : _min(nullptr), _max(nullptr), _median(nullptr), _mean(measurements.begin()->value().is_floating_point), _stddev(0.0) +{ + auto cmp_measurements = [](const Measurement & a, const Measurement & b) + { + return a.value() < b.value(); + }; + + auto add_measurements = [](Measurement::Value a, const Measurement & b) + { + return a + b.value(); + }; + + //Calculate min & max + const auto values = std::minmax_element(measurements.begin(), measurements.end(), cmp_measurements); + _min = &(*values.first); + _max = &(*values.second); + + // Calculate the median value + auto copy = measurements; + std::nth_element(copy.begin(), copy.begin() + (copy.size() / 2), copy.end(), cmp_measurements); + _median = ©[copy.size() / 2]; + + Measurement::Value sum_values = std::accumulate(measurements.begin(), measurements.end(), Measurement::Value(_min->value().is_floating_point), add_measurements); + + // Calculate the relative standard deviation + _mean = sum_values / measurements.size(); + std::vector diff(measurements.size(), _min->value().is_floating_point); + std::transform(measurements.begin(), measurements.end(), diff.begin(), [&](const Measurement & x) + { + return x.value() - _mean; + }); + auto sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), Measurement::Value(_min->value().is_floating_point)); + auto variance = sq_sum / measurements.size(); + _stddev = Measurement::Value::relative_standard_deviation(variance, _mean); +} +} // namespace framework +} // namespace test +} // namespace arm_compute diff --git a/tests/framework/instruments/InstrumentsStats.h b/tests/framework/instruments/InstrumentsStats.h new file mode 100644 index 0000000000..f1085aafb8 --- /dev/null +++ b/tests/framework/instruments/InstrumentsStats.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018 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. + */ +#ifndef ARM_COMPUTE_TEST_INSTRUMENTSMAP +#define ARM_COMPUTE_TEST_INSTRUMENTSMAP + +#include "Measurement.h" + +#include + +namespace arm_compute +{ +namespace test +{ +namespace framework +{ +/** Generate common statistics for a set of measurements + */ +class InstrumentsStats +{ +public: + /** Compute statistics for the passed set of measurements + * + * @param[in] measurements The measurements to process + */ + InstrumentsStats(const std::vector &measurements); + /** The measurement with the minimum value + */ + const Measurement &min() const + { + return *_min; + } + /** The measurement with the maximum value + */ + const Measurement &max() const + { + return *_max; + } + /** The median measurement + */ + const Measurement &median() const + { + return *_median; + } + /** The average of all the measurements + */ + const Measurement::Value &mean() const + { + return _mean; + } + /** The relative standard deviation of the measurements + */ + double relative_standard_deviation() const + { + return _stddev; + } + +private: + const Measurement *_min; + const Measurement *_max; + const Measurement *_median; + Measurement::Value _mean; + double _stddev; +}; + +} // namespace framework +} // namespace test +} // namespace arm_compute +#endif /* ARM_COMPUTE_TEST_INSTRUMENTSMAP */ diff --git a/tests/framework/printers/JSONPrinter.cpp b/tests/framework/printers/JSONPrinter.cpp index 676ec69336..6b982f5bb0 100644 --- a/tests/framework/printers/JSONPrinter.cpp +++ b/tests/framework/printers/JSONPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -179,26 +179,6 @@ void JSONPrinter::print_measurements(const Profiler::MeasurementsMap &measuremen { *_stream << R"(")" << i_it->first << R"(" : {)"; - auto add_measurements = [](Measurement::Value a, const Measurement & b) - { - return a + b.value(); - }; - - auto cmp_measurements = [](const Measurement & a, const Measurement & b) - { - return a.value() < b.value(); - }; - - 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(); - num_values -= 2; - } - auto measurement_to_string = [](const Measurement & measurement) { if(measurement.raw_data().size() == 1) @@ -214,14 +194,8 @@ void JSONPrinter::print_measurements(const Profiler::MeasurementsMap &measuremen return str.str(); } }; - *_stream << R"("avg" : )" << (sum_values / num_values) << ","; - 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" : ")" << i_it->second.begin()->unit() << R"(")"; *_stream << "}"; if(++i_it != i_end) diff --git a/tests/framework/printers/PrettyPrinter.cpp b/tests/framework/printers/PrettyPrinter.cpp index 085b2b900d..ef8f91a796 100644 --- a/tests/framework/printers/PrettyPrinter.cpp +++ b/tests/framework/printers/PrettyPrinter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -24,6 +24,7 @@ #include "PrettyPrinter.h" #include "../Framework.h" +#include "../instruments/InstrumentsStats.h" #include "../instruments/Measurement.h" #include @@ -121,50 +122,16 @@ void PrettyPrinter::print_measurements(const Profiler::MeasurementsMap &measurem { *_stream << begin_color("3") << " " << instrument.first << ":"; - auto add_measurements = [](Measurement::Value a, const Measurement & b) - { - return a + b.value(); - }; - - auto cmp_measurements = [](const Measurement & a, const Measurement & b) - { - return a.value() < b.value(); - }; - - 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); - - // Calculate the median value - auto measurements = instrument.second; - std::nth_element(measurements.begin(), measurements.begin() + (num_values / 2), measurements.end(), cmp_measurements); - const auto median_value = measurements[num_values / 2]; - - // Calculate the relative standard deviation - auto mean_value = sum_values / num_values; - std::vector diff(measurements.size(), minmax_values.first->value().is_floating_point); - std::transform(measurements.begin(), measurements.end(), diff.begin(), [mean_value](const Measurement & x) - { - return x.value() - mean_value; - }); - auto sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), Measurement::Value(minmax_values.first->value().is_floating_point)); - auto variance = sq_sum / measurements.size(); - auto rsd = Measurement::Value::relative_standard_deviation(variance, mean_value); - - if(num_values > 2) - { - sum_values -= minmax_values.first->value() + minmax_values.second->value(); - num_values -= 2; - } + InstrumentsStats stats(instrument.second); *_stream << " "; - *_stream << "MEDIAN=" << median_value.value() << " " << median_value.unit() << ", "; - *_stream << "AVG=" << (sum_values / num_values) << " " << minmax_values.second->unit() << ", "; - *_stream << "STDDEV=" << arithmetic_to_string(rsd, 2) << " %, "; - if(num_values > 1) + *_stream << "AVG=" << stats.mean() << " " << stats.max().unit(); + if(instrument.second.size() > 1) { - *_stream << "MIN=" << *minmax_values.first << ", "; - *_stream << "MAX=" << *minmax_values.second; + *_stream << ", STDDEV=" << arithmetic_to_string(stats.relative_standard_deviation(), 2) << " %"; + *_stream << ", MIN=" << stats.min() << ", "; + *_stream << ", MAX=" << stats.max() << ", "; + *_stream << ", MEDIAN=" << stats.median().value() << " " << stats.median().unit(); } *_stream << end_color() << "\n"; } -- cgit v1.2.1