summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAnthony Barbier <anthony.barbier@arm.com>2018-01-24 16:23:15 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-01-24 16:23:15 +0000
commitf45d5a9be1bf4d315a227b80617582b8eb4214d2 (patch)
tree29f24fc5f51448e831080d76eef3ac75d43c1934 /utils
parent6943bb00e79fe2ea4c127dc04b3440c5b0b29ce0 (diff)
downloadarmcl-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.cpp53
-rw-r--r--utils/GraphUtils.h53
-rw-r--r--utils/TypePrinter.h71
-rw-r--r--utils/Utils.cpp10
-rw-r--r--utils/Utils.h44
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");
}
}