diff options
author | Anthony Barbier <anthony.barbier@arm.com> | 2018-01-24 16:23:15 +0000 |
---|---|---|
committer | Anthony Barbier <anthony.barbier@arm.com> | 2018-01-24 16:23:15 +0000 |
commit | f45d5a9be1bf4d315a227b80617582b8eb4214d2 (patch) | |
tree | 29f24fc5f51448e831080d76eef3ac75d43c1934 /utils | |
parent | 6943bb00e79fe2ea4c127dc04b3440c5b0b29ce0 (diff) | |
download | armcl-f45d5a9be1bf4d315a227b80617582b8eb4214d2.tar.gz armcl-f45d5a9be1bf4d315a227b80617582b8eb4214d2.tar.bz2 armcl-f45d5a9be1bf4d315a227b80617582b8eb4214d2.zip |
arm_compute v18.01
Change-Id: I9bfa178c2e38bfd5fc812e62aab6760d87748e05
Diffstat (limited to 'utils')
-rw-r--r-- | utils/GraphUtils.cpp | 53 | ||||
-rw-r--r-- | utils/GraphUtils.h | 53 | ||||
-rw-r--r-- | utils/TypePrinter.h | 71 | ||||
-rw-r--r-- | utils/Utils.cpp | 10 | ||||
-rw-r--r-- | utils/Utils.h | 44 |
5 files changed, 186 insertions, 45 deletions
diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp index b9be9d408..2ff40b7fb 100644 --- a/utils/GraphUtils.cpp +++ b/utils/GraphUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -30,13 +30,7 @@ #include "arm_compute/runtime/CL/CLTensor.h" #endif /* ARM_COMPUTE_CL */ -#include "arm_compute/core/Error.h" -#include "arm_compute/core/PixelValue.h" - -#include <algorithm> #include <iomanip> -#include <ostream> -#include <random> using namespace arm_compute::graph_utils; @@ -80,8 +74,10 @@ bool DummyAccessor::access_tensor(ITensor &tensor) return ret; } -PPMAccessor::PPMAccessor(const std::string &ppm_path, bool bgr, float mean_r, float mean_g, float mean_b) - : _ppm_path(ppm_path), _bgr(bgr), _mean_r(mean_r), _mean_g(mean_g), _mean_b(mean_b) +PPMAccessor::PPMAccessor(std::string ppm_path, bool bgr, + float mean_r, float mean_g, float mean_b, + float std_r, float std_g, float std_b) + : _ppm_path(std::move(ppm_path)), _bgr(bgr), _mean_r(mean_r), _mean_g(mean_g), _mean_b(mean_b), _std_r(std_r), _std_g(std_g), _std_b(std_b) { } @@ -94,6 +90,12 @@ bool PPMAccessor::access_tensor(ITensor &tensor) _mean_g, _bgr ? _mean_r : _mean_b }; + const float std[3] = + { + _bgr ? _std_b : _std_r, + _std_g, + _bgr ? _std_r : _std_b + }; // Open PPM file ppm.open(_ppm_path); @@ -111,7 +113,7 @@ bool PPMAccessor::access_tensor(ITensor &tensor) execute_window_loop(window, [&](const Coordinates & id) { const float value = *reinterpret_cast<float *>(tensor.ptr_to_element(id)) - mean[id.z()]; - *reinterpret_cast<float *>(tensor.ptr_to_element(id)) = value; + *reinterpret_cast<float *>(tensor.ptr_to_element(id)) = value / std[id.z()]; }); return true; @@ -140,16 +142,14 @@ TopNPredictionsAccessor::TopNPredictionsAccessor(const std::string &labels_path, } } -bool TopNPredictionsAccessor::access_tensor(ITensor &tensor) +template <typename T> +void TopNPredictionsAccessor::access_predictions_tensor(ITensor &tensor) { - ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::F32); - ARM_COMPUTE_ERROR_ON(_labels.size() != tensor.info()->dimension(0)); - // Get the predicted class - std::vector<float> classes_prob; + std::vector<T> classes_prob; std::vector<size_t> index; - const auto output_net = reinterpret_cast<float *>(tensor.buffer() + tensor.info()->offset_first_element_in_bytes()); + const auto output_net = reinterpret_cast<T *>(tensor.buffer() + tensor.info()->offset_first_element_in_bytes()); const size_t num_classes = tensor.info()->dimension(0); classes_prob.resize(num_classes); @@ -170,10 +170,28 @@ bool TopNPredictionsAccessor::access_tensor(ITensor &tensor) for(size_t i = 0; i < _top_n; ++i) { _output_stream << std::fixed << std::setprecision(4) - << classes_prob[index.at(i)] + << +classes_prob[index.at(i)] << " - [id = " << index.at(i) << "]" << ", " << _labels[index.at(i)] << std::endl; } +} + +bool TopNPredictionsAccessor::access_tensor(ITensor &tensor) +{ + ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::F32, DataType::QASYMM8); + ARM_COMPUTE_ERROR_ON(_labels.size() != tensor.info()->dimension(0)); + + switch(tensor.info()->data_type()) + { + case DataType::QASYMM8: + access_predictions_tensor<uint8_t>(tensor); + break; + case DataType::F32: + access_predictions_tensor<float>(tensor); + break; + default: + ARM_COMPUTE_ERROR("NOT SUPPORTED!"); + } return false; } @@ -314,6 +332,7 @@ bool NumPyBinLoader::access_tensor(ITensor &tensor) // Validate tensor shape ARM_COMPUTE_ERROR_ON_MSG(shape.size() != tensor_shape.num_dimensions(), "Tensor ranks mismatch"); + if(fortran_order) { for(size_t i = 0; i < shape.size(); ++i) diff --git a/utils/GraphUtils.h b/utils/GraphUtils.h index 429394d1c..da52c2652 100644 --- a/utils/GraphUtils.h +++ b/utils/GraphUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -90,8 +90,13 @@ public: * @param[in] mean_r (Optional) Red mean value to be subtracted from red channel * @param[in] mean_g (Optional) Green mean value to be subtracted from green channel * @param[in] mean_b (Optional) Blue mean value to be subtracted from blue channel + * @param[in] std_r (Optional) Red standard deviation value to be divided from red channel + * @param[in] std_g (Optional) Green standard deviation value to be divided from green channel + * @param[in] std_b (Optional) Blue standard deviation value to be divided from blue channel */ - PPMAccessor(const std::string &ppm_path, bool bgr = true, float mean_r = 0.0f, float mean_g = 0.0f, float mean_b = 0.0f); + PPMAccessor(std::string ppm_path, bool bgr = true, + float mean_r = 0.0f, float mean_g = 0.0f, float mean_b = 0.0f, + float std_r = 1.f, float std_g = 1.f, float std_b = 1.f); /** Allow instances of this class to be move constructed */ PPMAccessor(PPMAccessor &&) = default; @@ -99,11 +104,14 @@ public: bool access_tensor(ITensor &tensor) override; private: - const std::string &_ppm_path; - const bool _bgr; - const float _mean_r; - const float _mean_g; - const float _mean_b; + const std::string _ppm_path; + const bool _bgr; + const float _mean_r; + const float _mean_g; + const float _mean_b; + const float _std_r; + const float _std_g; + const float _std_b; }; /** Result accessor class */ @@ -128,6 +136,9 @@ public: bool access_tensor(ITensor &tensor) override; private: + template <typename T> + void access_predictions_tensor(ITensor &tensor); + std::vector<std::string> _labels; std::ostream &_output_stream; size_t _top_n; @@ -177,6 +188,19 @@ private: const std::string _filename; }; +/** Generates appropriate random accessor + * + * @param[in] lower Lower random values bound + * @param[in] upper Upper random values bound + * @param[in] seed Random generator seed + * + * @return A ramdom accessor + */ +inline std::unique_ptr<graph::ITensorAccessor> get_random_accessor(PixelValue lower, PixelValue upper, const std::random_device::result_type seed = 0) +{ + return arm_compute::support::cpp14::make_unique<RandomAccessor>(lower, upper, seed); +} + /** Generates appropriate weights accessor according to the specified path * * @note If path is empty will generate a DummyAccessor else will generate a NumPyBinLoader @@ -206,10 +230,17 @@ inline std::unique_ptr<graph::ITensorAccessor> get_weights_accessor(const std::s * @param[in] mean_r Red mean value to be subtracted from red channel * @param[in] mean_g Green mean value to be subtracted from green channel * @param[in] mean_b Blue mean value to be subtracted from blue channel + * @param[in] std_r (Optional) Red standard deviation value to be divided from red channel + * @param[in] std_g (Optional) Green standard deviation value to be divided from green channel + * @param[in] std_b (Optional) Blue standard deviation value to be divided from blue channel + * @param[in] bgr (Optional) Fill the first plane with blue channel (default = true) * * @return An appropriate tensor accessor */ -inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::string &ppm_path, float mean_r, float mean_g, float mean_b) +inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::string &ppm_path, + float mean_r = 0.f, float mean_g = 0.f, float mean_b = 0.f, + float std_r = 1.f, float std_g = 1.f, float std_b = 1.f, + bool bgr = true) { if(ppm_path.empty()) { @@ -217,7 +248,9 @@ inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::str } else { - return arm_compute::support::cpp14::make_unique<PPMAccessor>(ppm_path, true, mean_r, mean_g, mean_b); + return arm_compute::support::cpp14::make_unique<PPMAccessor>(ppm_path, bgr, + mean_r, mean_g, mean_b, + std_r, std_g, std_b); } } @@ -255,7 +288,7 @@ inline std::unique_ptr<graph::ITensorAccessor> get_output_accessor(const std::st { if(labels_path.empty()) { - return arm_compute::support::cpp14::make_unique<DummyAccessor>(); + return arm_compute::support::cpp14::make_unique<DummyAccessor>(0); } else { diff --git a/utils/TypePrinter.h b/utils/TypePrinter.h index a180dd349..2dc2d787d 100644 --- a/utils/TypePrinter.h +++ b/utils/TypePrinter.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017, 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -26,6 +26,8 @@ #include "arm_compute/core/Dimensions.h" #include "arm_compute/core/Error.h" +#include "arm_compute/core/HOGInfo.h" +#include "arm_compute/core/Size2D.h" #include "arm_compute/core/Strides.h" #include "arm_compute/core/TensorInfo.h" #include "arm_compute/core/Types.h" @@ -855,5 +857,72 @@ inline std::string to_string(const arm_compute::GradientDimension &type) str << type; return str.str(); } + +/** Formatted output of the HOGNormType type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const HOGNormType &norm_type) +{ + switch(norm_type) + { + case HOGNormType::L1_NORM: + os << "L1_NORM"; + break; + case HOGNormType::L2_NORM: + os << "L2_NORM"; + break; + case HOGNormType::L2HYS_NORM: + os << "L2HYS_NORM"; + break; + default: + ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); + } + + return os; +} + +inline std::string to_string(const HOGNormType &type) +{ + std::stringstream str; + str << type; + return str.str(); +} + +/** Formatted output of the Size2D type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const Size2D &size) +{ + os << size.width << "x" << size.height; + + return os; +} + +inline std::string to_string(const Size2D &type) +{ + std::stringstream str; + str << type; + return str.str(); +} + +/** Formatted output of the Size2D type. */ +inline ::std::ostream &operator<<(::std::ostream &os, const HOGInfo &hog_info) +{ + os << "{CellSize=" << hog_info.cell_size() << "," + << "BlockSize=" << hog_info.block_size() << "," + << "DetectionWindowSize=" << hog_info.detection_window_size() << "," + << "BlockStride=" << hog_info.block_stride() << "," + << "NumBins=" << hog_info.num_bins() << "," + << "NormType=" << hog_info.normalization_type() << "," + << "L2HystThreshold=" << hog_info.l2_hyst_threshold() << "," + << "PhaseType=" << hog_info.phase_type() << "}"; + + return os; +} + +/** Formatted output of the HOGInfo type. */ +inline std::string to_string(const HOGInfo &type) +{ + std::stringstream str; + str << type; + return str.str(); +} + } // namespace arm_compute #endif /* __ARM_COMPUTE_TEST_TYPE_PRINTER_H__ */ diff --git a/utils/Utils.cpp b/utils/Utils.cpp index f6aff6f92..32d5e3a6c 100644 --- a/utils/Utils.cpp +++ b/utils/Utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 ARM Limited. + * Copyright (c) 2017, 2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -66,14 +66,17 @@ void discard_comments_and_spaces(std::ifstream &fs) } } // namespace -int run_example(int argc, const char **argv, example &func) +#ifndef BENCHMARK_EXAMPLES +int run_example(int argc, char **argv, Example &example) { std::cout << "\n" << argv[0] << "\n\n"; try { - func(argc, argv); + example.do_setup(argc, argv); + example.do_run(); + example.do_teardown(); std::cout << "\nTest passed\n"; return 0; @@ -99,6 +102,7 @@ int run_example(int argc, const char **argv, example &func) return -1; } +#endif /* BENCHMARK_EXAMPLES */ void draw_detection_rectangle(ITensor *tensor, const DetectionWindow &rect, uint8_t r, uint8_t g, uint8_t b) { diff --git a/utils/Utils.h b/utils/Utils.h index cfc9c8cb1..83468d861 100644 --- a/utils/Utils.h +++ b/utils/Utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017 ARM Limited. + * Copyright (c) 2016-2018 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -55,20 +55,35 @@ namespace arm_compute { namespace utils { -/** Signature of an example to run +/** Abstract Example class. * - * @param[in] argc Number of command line arguments - * @param[in] argv Command line arguments + * All examples have to inherit from this class. */ -using example = void(int argc, const char **argv); +class Example +{ +public: + virtual void do_setup(int argc, char **argv) {}; + virtual void do_run() {}; + virtual void do_teardown() {}; + + /** Default destructor. */ + virtual ~Example() = default; +}; /** Run an example and handle the potential exceptions it throws * - * @param[in] argc Number of command line arguments - * @param[in] argv Command line arguments - * @param[in] func Pointer to the function containing the code to run + * @param[in] argc Number of command line arguments + * @param[in] argv Command line arguments + * @param[in] example Example to run */ -int run_example(int argc, const char **argv, example &func); +int run_example(int argc, char **argv, Example &example); + +template <typename T> +int run_example(int argc, char **argv) +{ + T example; + return run_example(argc, argv, example); +} /** Draw a RGB rectangular window for the detected object * @@ -123,6 +138,7 @@ inline std::string get_typestring(DataType data_type) switch(data_type) { case DataType::U8: + case DataType::QASYMM8: return no_endianness + "u" + support::cpp11::to_string(sizeof(uint8_t)); case DataType::S8: return no_endianness + "i" + support::cpp11::to_string(sizeof(int8_t)); @@ -258,7 +274,7 @@ public: ARM_COMPUTE_ERROR_ON_MSG(max_val >= 256, "2 bytes per colour channel not supported in file %s", ppm_filename.c_str()); } - catch(const std::ifstream::failure &e) + catch(std::runtime_error &e) { ARM_COMPUTE_ERROR("Accessing %s: %s", ppm_filename.c_str(), e.what()); } @@ -545,7 +561,7 @@ public: void fill_tensor(T &tensor) { ARM_COMPUTE_ERROR_ON(!is_open()); - ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(&tensor, arm_compute::DataType::F32); + ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(&tensor, arm_compute::DataType::F32); try { // Map buffer if creating a CLTensor @@ -566,19 +582,19 @@ public: ARM_COMPUTE_ERROR_ON_MSG(_typestring != expect_typestr, "Typestrings mismatch"); // Validate tensor shape - ARM_COMPUTE_ERROR_ON_MSG(_shape.size() != tensor.shape().num_dimensions(), "Tensor ranks mismatch"); + ARM_COMPUTE_ERROR_ON_MSG(_shape.size() != tensor.info()->tensor_shape().num_dimensions(), "Tensor ranks mismatch"); if(_fortran_order) { for(size_t i = 0; i < _shape.size(); ++i) { - ARM_COMPUTE_ERROR_ON_MSG(tensor.shape()[i] != _shape[i], "Tensor dimensions mismatch"); + ARM_COMPUTE_ERROR_ON_MSG(tensor.info()->tensor_shape()[i] != _shape[i], "Tensor dimensions mismatch"); } } else { for(size_t i = 0; i < _shape.size(); ++i) { - ARM_COMPUTE_ERROR_ON_MSG(tensor.shape()[i] != _shape[_shape.size() - i - 1], "Tensor dimensions mismatch"); + ARM_COMPUTE_ERROR_ON_MSG(tensor.info()->tensor_shape()[i] != _shape[_shape.size() - i - 1], "Tensor dimensions mismatch"); } } |