summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAnthony Barbier <anthony.barbier@arm.com>2018-02-22 15:45:35 +0000
committerAnthony Barbier <anthony.barbier@arm.com>2018-02-23 11:49:54 +0000
commit06ea048f062a50404b1b3998a61a45449c2d1f0f (patch)
treeaa0dea3b0c49422538df9a5a02578b2c29e6fa67 /utils
parent292227986edb37b01061afcad6df18ba9d6ccbeb (diff)
downloadarmcl-06ea048f062a50404b1b3998a61a45449c2d1f0f.tar.gz
armcl-06ea048f062a50404b1b3998a61a45449c2d1f0f.tar.bz2
armcl-06ea048f062a50404b1b3998a61a45449c2d1f0f.zip
arm_compute v18.02
Change-Id: I7207aa488e5470f235f39b6c188b4678dc38d1a6
Diffstat (limited to 'utils')
-rw-r--r--utils/GraphUtils.cpp105
-rw-r--r--utils/GraphUtils.h87
-rw-r--r--utils/TypePrinter.h81
-rw-r--r--utils/Utils.cpp36
-rw-r--r--utils/Utils.h6
5 files changed, 235 insertions, 80 deletions
diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp
index f190af488..448343a97 100644
--- a/utils/GraphUtils.cpp
+++ b/utils/GraphUtils.cpp
@@ -23,8 +23,9 @@
*/
#include "utils/GraphUtils.h"
-#include "utils/Utils.h"
+
#include "arm_compute/runtime/SubTensor.h"
+#include "utils/Utils.h"
#ifdef ARM_COMPUTE_CL
#include "arm_compute/core/CL/OpenCL.h"
@@ -35,6 +36,41 @@
using namespace arm_compute::graph_utils;
+void TFPreproccessor::preprocess(ITensor &tensor)
+{
+ Window window;
+ window.use_tensor_dimensions(tensor.info()->tensor_shape());
+
+ execute_window_loop(window, [&](const Coordinates & id)
+ {
+ const float value = *reinterpret_cast<float *>(tensor.ptr_to_element(id));
+ float res = value / 255.f; // Normalize to [0, 1]
+ res = (res - 0.5f) * 2.f; // Map to [-1, 1]
+ *reinterpret_cast<float *>(tensor.ptr_to_element(id)) = res;
+ });
+}
+
+CaffePreproccessor::CaffePreproccessor(std::array<float, 3> mean, bool bgr)
+ : _mean(mean), _bgr(bgr)
+{
+ if(_bgr)
+ {
+ std::swap(_mean[0], _mean[2]);
+ }
+}
+
+void CaffePreproccessor::preprocess(ITensor &tensor)
+{
+ Window window;
+ window.use_tensor_dimensions(tensor.info()->tensor_shape());
+
+ 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;
+ });
+}
+
PPMWriter::PPMWriter(std::string name, unsigned int maximum)
: _name(std::move(name)), _iterator(0), _maximum(maximum)
{
@@ -75,28 +111,14 @@ bool DummyAccessor::access_tensor(ITensor &tensor)
return ret;
}
-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)
+PPMAccessor::PPMAccessor(std::string ppm_path, bool bgr, std::unique_ptr<IPreprocessor> preprocessor)
+ : _ppm_path(std::move(ppm_path)), _bgr(bgr), _preprocessor(std::move(preprocessor))
{
}
bool PPMAccessor::access_tensor(ITensor &tensor)
{
utils::PPMLoader ppm;
- const float mean[3] =
- {
- _bgr ? _mean_b : _mean_r,
- _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);
@@ -107,15 +129,11 @@ bool PPMAccessor::access_tensor(ITensor &tensor)
// Fill the tensor with the PPM content (BGR)
ppm.fill_planar_tensor(tensor, _bgr);
- // Subtract the mean value from each channel
- Window window;
- window.use_tensor_dimensions(tensor.info()->tensor_shape());
-
- execute_window_loop(window, [&](const Coordinates & id)
+ // Preprocess tensor
+ if(_preprocessor)
{
- const float value = *reinterpret_cast<float *>(tensor.ptr_to_element(id)) - mean[id.z()];
- *reinterpret_cast<float *>(tensor.ptr_to_element(id)) = value / std[id.z()];
- });
+ _preprocessor->preprocess(tensor);
+ }
return true;
}
@@ -207,7 +225,7 @@ void RandomAccessor::fill(ITensor &tensor, D &&distribution)
{
std::mt19937 gen(_seed);
- if(tensor.info()->padding().empty() && !dynamic_cast<SubTensor*>(&tensor))
+ if(tensor.info()->padding().empty() && (dynamic_cast<SubTensor *>(&tensor) == nullptr))
{
for(size_t offset = 0; offset < tensor.info()->total_size(); offset += tensor.info()->element_size())
{
@@ -331,26 +349,39 @@ bool NumPyBinLoader::access_tensor(ITensor &tensor)
std::string expect_typestr = arm_compute::utils::get_typestring(tensor.info()->data_type());
ARM_COMPUTE_ERROR_ON_MSG(typestr != expect_typestr, "Typestrings mismatch");
- // Validate tensor shape
- ARM_COMPUTE_ERROR_ON_MSG(shape.size() != tensor_shape.num_dimensions(), "Tensor ranks mismatch");
+ // Reverse vector in case of non fortran order
+ if(!fortran_order)
+ {
+ std::reverse(shape.begin(), shape.end());
+ }
- if(fortran_order)
+ // Correct dimensions (Needs to match TensorShape dimension corrections)
+ if(shape.size() != tensor_shape.num_dimensions())
{
- for(size_t i = 0; i < shape.size(); ++i)
+ for(int i = static_cast<int>(shape.size()) - 1; i > 0; --i)
{
- ARM_COMPUTE_ERROR_ON_MSG(tensor_shape[i] != shape[i], "Tensor dimensions mismatch");
+ if(shape[i] == 1)
+ {
+ shape.pop_back();
+ }
+ else
+ {
+ break;
+ }
}
}
- else
+
+ // Validate tensor ranks
+ ARM_COMPUTE_ERROR_ON_MSG(shape.size() != tensor_shape.num_dimensions(), "Tensor ranks mismatch");
+
+ // Validate shapes
+ for(size_t i = 0; i < shape.size(); ++i)
{
- 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_shape[i] != shape[i], "Tensor dimensions mismatch");
}
// Read data
- if(tensor.info()->padding().empty() && !dynamic_cast<SubTensor*>(&tensor))
+ if(tensor.info()->padding().empty() && (dynamic_cast<SubTensor *>(&tensor) == nullptr))
{
// If tensor has no padding read directly from stream.
stream.read(reinterpret_cast<char *>(tensor.buffer()), tensor.info()->total_size());
diff --git a/utils/GraphUtils.h b/utils/GraphUtils.h
index da52c2652..cc6f40417 100644
--- a/utils/GraphUtils.h
+++ b/utils/GraphUtils.h
@@ -29,6 +29,7 @@
#include "arm_compute/graph/ITensorAccessor.h"
#include "arm_compute/graph/Types.h"
+#include <array>
#include <random>
#include <string>
#include <vector>
@@ -37,6 +38,38 @@ namespace arm_compute
{
namespace graph_utils
{
+/** Preprocessor interface **/
+class IPreprocessor
+{
+public:
+ virtual ~IPreprocessor() = default;
+ virtual void preprocess(ITensor &tensor) = 0;
+};
+
+/** Caffe preproccessor */
+class CaffePreproccessor : public IPreprocessor
+{
+public:
+ /** Default Constructor
+ *
+ * @param mean Mean array in RGB ordering
+ * @param bgr Boolean specifying if the preprocessing should assume BGR format
+ */
+ CaffePreproccessor(std::array<float, 3> mean = std::array<float, 3> { { 0, 0, 0 } }, bool bgr = true);
+ void preprocess(ITensor &tensor) override;
+
+private:
+ std::array<float, 3> _mean;
+ bool _bgr;
+};
+
+/** TF preproccessor */
+class TFPreproccessor : public IPreprocessor
+{
+public:
+ void preprocess(ITensor &tensor) override;
+};
+
/** PPM writer class */
class PPMWriter : public graph::ITensorAccessor
{
@@ -85,18 +118,11 @@ class PPMAccessor final : public graph::ITensorAccessor
public:
/** Constructor
*
- * @param[in] ppm_path Path to PPM file
- * @param[in] bgr (Optional) Fill the first plane with blue channel (default = false)
- * @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
+ * @param[in] ppm_path Path to PPM file
+ * @param[in] bgr (Optional) Fill the first plane with blue channel (default = false)
+ * @param[in] preprocessor (Optional) PPM pre-processing object
*/
- 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);
+ PPMAccessor(std::string ppm_path, bool bgr = true, std::unique_ptr<IPreprocessor> preprocessor = nullptr);
/** Allow instances of this class to be move constructed */
PPMAccessor(PPMAccessor &&) = default;
@@ -104,14 +130,9 @@ 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 float _std_r;
- const float _std_g;
- const float _std_b;
+ const std::string _ppm_path;
+ const bool _bgr;
+ std::unique_ptr<IPreprocessor> _preprocessor;
};
/** Result accessor class */
@@ -226,21 +247,15 @@ inline std::unique_ptr<graph::ITensorAccessor> get_weights_accessor(const std::s
*
* @note If ppm_path is empty will generate a DummyAccessor else will generate a PPMAccessor
*
- * @param[in] ppm_path Path to PPM file
- * @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)
+ * @param[in] ppm_path Path to PPM file
+ * @param[in] preprocessor Preproccessor object
+ * @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 = 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)
+inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::string &ppm_path,
+ std::unique_ptr<IPreprocessor> preprocessor = nullptr,
+ bool bgr = true)
{
if(ppm_path.empty())
{
@@ -248,22 +263,20 @@ inline std::unique_ptr<graph::ITensorAccessor> get_input_accessor(const std::str
}
else
{
- return arm_compute::support::cpp14::make_unique<PPMAccessor>(ppm_path, bgr,
- mean_r, mean_g, mean_b,
- std_r, std_g, std_b);
+ return arm_compute::support::cpp14::make_unique<PPMAccessor>(ppm_path, bgr, std::move(preprocessor));
}
}
/** Utility function to return the TargetHint
*
- * @param[in] target Integer value which expresses the selected target. Must be 0 for NEON or 1 for OpenCL
+ * @param[in] target Integer value which expresses the selected target. Must be 0 for NEON, 1 for OpenCL or 2 for OpenCL with Tuner
*
* @return the TargetHint
*/
inline graph::TargetHint set_target_hint(int target)
{
- ARM_COMPUTE_ERROR_ON_MSG(target > 1, "Invalid target. Target must be 0 (NEON) or 1 (OpenCL)");
- if(target == 1 && graph::Graph::opencl_is_available())
+ ARM_COMPUTE_ERROR_ON_MSG(target > 2, "Invalid target. Target must be 0 (NEON), 1 (OpenCL) or 2 (OpenCL with Tuner)");
+ if((target == 1 || target == 2) && graph::Graph::opencl_is_available())
{
// If type of target is OpenCL, check if OpenCL is available and initialize the scheduler
return graph::TargetHint::OPENCL;
diff --git a/utils/TypePrinter.h b/utils/TypePrinter.h
index 2dc2d787d..313fad1a5 100644
--- a/utils/TypePrinter.h
+++ b/utils/TypePrinter.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 ARM Limited.
+ * Copyright (c) 2017-2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -24,6 +24,7 @@
#ifndef __ARM_COMPUTE_TEST_TYPE_PRINTER_H__
#define __ARM_COMPUTE_TEST_TYPE_PRINTER_H__
+#include "arm_compute/core/CL/CLTypes.h"
#include "arm_compute/core/Dimensions.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/core/HOGInfo.h"
@@ -290,14 +291,14 @@ inline ::std::ostream &operator<<(::std::ostream &os, const NormType &norm_type)
inline std::string to_string(const arm_compute::NormalizationLayerInfo &info)
{
std::stringstream str;
- str << info.type();
+ str << info.type() << ":NormSize=" << info.norm_size();
return str.str();
}
/** Formatted output of @ref NormalizationLayerInfo. */
inline ::std::ostream &operator<<(::std::ostream &os, const NormalizationLayerInfo &info)
{
- os << info.type();
+ os << info.type() << ":NormSize=" << info.norm_size();
return os;
}
@@ -522,6 +523,13 @@ inline ::std::ostream &operator<<(::std::ostream &os, const Channel &channel)
return os;
}
+inline std::string to_string(const Channel &channel)
+{
+ std::stringstream str;
+ str << channel;
+ return str.str();
+}
+
/** Formatted output of the BorderMode type. */
inline ::std::ostream &operator<<(::std::ostream &os, const BorderMode &mode)
{
@@ -759,7 +767,7 @@ inline std::string to_string(const PoolingLayerInfo &info)
if(!info.is_global_pooling())
{
str << ","
- << "PoolSize=" << info.pool_size() << ","
+ << "PoolSize=" << info.pool_size().width << "," << info.pool_size().height << ","
<< "PadStride=" << info.pad_stride_info();
}
str << "}";
@@ -924,5 +932,70 @@ inline std::string to_string(const HOGInfo &type)
return str.str();
}
+inline ::std::ostream &operator<<(::std::ostream &os, const ConvolutionMethod &conv_method)
+{
+ switch(conv_method)
+ {
+ case ConvolutionMethod::GEMM:
+ os << "GEMM";
+ break;
+ case ConvolutionMethod::DIRECT:
+ os << "DIRECT";
+ break;
+ case ConvolutionMethod::WINOGRAD:
+ os << "WINOGRAD";
+ break;
+ default:
+ ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+ }
+
+ return os;
+}
+
+inline std::string to_string(const ConvolutionMethod &conv_method)
+{
+ std::stringstream str;
+ str << conv_method;
+ return str.str();
+}
+
+inline ::std::ostream &operator<<(::std::ostream &os, const GPUTarget &gpu_target)
+{
+ switch(gpu_target)
+ {
+ case GPUTarget::GPU_ARCH_MASK:
+ os << "GPU_ARCH_MASK";
+ break;
+ case GPUTarget::MIDGARD:
+ os << "MIDGARD";
+ break;
+ case GPUTarget::BIFROST:
+ os << "BIFROST";
+ break;
+ case GPUTarget::T600:
+ os << "T600";
+ break;
+ case GPUTarget::T700:
+ os << "T700";
+ break;
+ case GPUTarget::T800:
+ os << "T800";
+ break;
+ case GPUTarget::G70:
+ os << "G70";
+ break;
+ default:
+ ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
+ }
+
+ return os;
+}
+
+inline std::string to_string(const GPUTarget &gpu_target)
+{
+ std::stringstream str;
+ str << gpu_target;
+ return str.str();
+}
} // namespace arm_compute
#endif /* __ARM_COMPUTE_TEST_TYPE_PRINTER_H__ */
diff --git a/utils/Utils.cpp b/utils/Utils.cpp
index 32d5e3a6c..8a2d11814 100644
--- a/utils/Utils.cpp
+++ b/utils/Utils.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2018 ARM Limited.
+ * Copyright (c) 2017-2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -191,5 +191,39 @@ std::tuple<std::vector<unsigned long>, bool, std::string> parse_npy_header(std::
return std::make_tuple(shape, fortran_order, typestr);
}
+
+/** This function returns the amount of memory free reading from /proc/meminfo
+ *
+ * @return The free memory in kB
+ */
+uint64_t get_mem_free_from_meminfo()
+{
+ std::string line_attribute;
+ std::ifstream file_meminfo("/proc/meminfo");
+
+ if(file_meminfo.is_open())
+ {
+ while(!(file_meminfo >> line_attribute).fail())
+ {
+ //Test if is the line containing MemFree
+ if(line_attribute == "MemFree:")
+ {
+ uint64_t mem_available;
+ if(!(file_meminfo >> mem_available).fail())
+ {
+ return mem_available;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ // if it's not MemFree ignore rest of the line
+ file_meminfo.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+ }
+ }
+ // Nothing found or an error during opening the file
+ return 0;
+}
} // namespace utils
} // namespace arm_compute
diff --git a/utils/Utils.h b/utils/Utils.h
index 83468d861..4cce39fbc 100644
--- a/utils/Utils.h
+++ b/utils/Utils.h
@@ -895,7 +895,11 @@ void init_sgemm_output(T &dst, T &src0, T &src1, arm_compute::DataType dt)
{
dst.allocator()->init(TensorInfo(TensorShape(src1.info()->dimension(0), src0.info()->dimension(1)), 1, dt));
}
-
+/** This function returns the amount of memory free reading from /proc/meminfo
+ *
+ * @return The free memory in kB
+ */
+uint64_t get_mem_free_from_meminfo();
} // namespace utils
} // namespace arm_compute
#endif /* __UTILS_UTILS_H__*/