24 #ifndef __UTILS_UTILS_H__ 25 #define __UTILS_UTILS_H__ 36 #pragma GCC diagnostic push 37 #pragma GCC diagnostic ignored "-Wunused-parameter" 38 #pragma GCC diagnostic ignored "-Wstrict-overflow" 39 #include "libnpy/npy.hpp" 40 #pragma GCC diagnostic pop 108 int run_example(
int argc,
char **argv, std::unique_ptr<Example> example);
110 template <
typename T>
113 return run_example(argc, argv, std::make_unique<T>());
141 std::tuple<unsigned int, unsigned int, int>
parse_ppm_header(std::ifstream &fs);
150 std::tuple<std::vector<unsigned long>, bool, std::string>
parse_npy_header(std::ifstream &fs);
161 const unsigned int i = 1;
162 const char *c =
reinterpret_cast<const char *
>(&i);
163 std::string endianness;
166 endianness = std::string(
"<");
170 endianness = std::string(
">");
172 const std::string no_endianness(
"|");
215 template <
typename T>
216 inline void map(T &tensor,
bool blocking)
226 template <
typename T>
232 #ifdef ARM_COMPUTE_CL 240 tensor.
map(blocking);
259 distribution.
map(blocking);
268 distribution.
unmap();
272 #ifdef ARM_COMPUTE_GC 280 tensor.
map(blocking);
297 template <
typename T>
300 static_assert(std::is_same<T, half>::value || std::is_same<T, bfloat16>::value,
"Only half and bfloat16 data types supported");
324 std::uniform_real_distribution<float> dist;
333 : _fs(), _shape(), _fortran_order(false), _typestring(), _file_layout(
DataLayout::
NCHW)
347 _fs.open(npy_filename, std::ios::in | std::ios::binary);
349 _fs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
350 _file_layout = file_layout;
354 catch(
const std::ifstream::failure &e)
362 return _fs.is_open();
368 return _fortran_order;
376 template <
typename T>
385 for(
size_t i = 0; i < _shape.size(); ++i)
390 src = _shape.size() - 1 - i;
392 shape.
set(i, _shape.at(src));
396 tensor.allocator()->init(tensor_info);
405 template <
typename T>
416 const size_t current_position = _fs.tellg();
418 const size_t end_position = _fs.tellg();
419 _fs.seekg(current_position, std::ios_base::beg);
421 ARM_COMPUTE_ERROR_ON_MSG((end_position - current_position) < tensor.info()->tensor_shape().total_size() * tensor.info()->element_size(),
422 "Not enough data in file");
426 std::string expect_typestr =
get_typestring(tensor.info()->data_type());
429 bool are_layouts_different = (_file_layout != tensor.info()->data_layout());
431 if(_shape.size() != tensor.info()->tensor_shape().num_dimensions())
433 for(
int i = static_cast<int>(_shape.size()) - 1; i > 0; --i)
446 TensorShape permuted_shape = tensor.info()->tensor_shape();
448 if(are_layouts_different && tensor.info()->tensor_shape().num_dimensions() > 2)
458 for(
size_t i = 0; i < _shape.size(); ++i)
463 switch(tensor.info()->data_type())
471 if(!are_layouts_different && !_fortran_order && tensor.info()->padding().empty())
474 _fs.read(reinterpret_cast<char *>(tensor.buffer()), tensor.info()->total_size());
480 const unsigned int num_dims = _shape.size();
483 for(
unsigned int dim = 0; dim < num_dims; dim++)
485 permuted_shape.
set(dim, _shape[num_dims - dim - 1]);
486 perm.
set(dim, num_dims - dim - 1);
488 if(are_layouts_different)
510 _fs.read(reinterpret_cast<char *>(tensor.ptr_to_element(dst)), tensor.info()->element_size());
523 catch(
const std::ifstream::failure &e)
531 std::vector<unsigned long> _shape;
533 std::string _typestring;
546 template <
typename T>
556 fs.exceptions(std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit);
557 fs.open(ppm_filename, std::ios::out | std::ios::binary);
559 const unsigned int width = tensor.info()->tensor_shape()[0];
560 const unsigned int height = tensor.info()->tensor_shape()[1];
563 << width <<
" " << height <<
" 255\n";
568 switch(tensor.info()->format())
580 const unsigned char value = *in.
ptr();
582 fs << value << value << value;
598 fs.write(reinterpret_cast<std::fstream::char_type *>(in.
ptr()), width * tensor.info()->element_size());
611 catch(
const std::ofstream::failure &e)
626 template <
typename T,
typename U =
float>
627 void save_to_npy(T &tensor,
const std::string &npy_filename,
bool fortran_order)
634 fs.exceptions(std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit);
635 fs.open(npy_filename, std::ios::out | std::ios::binary);
637 std::vector<npy::ndarray_len_t>
shape(tensor.info()->num_dimensions());
639 for(
unsigned int i = 0, j = tensor.info()->num_dimensions() - 1; i < tensor.info()->num_dimensions(); ++i, --j)
641 shape[i] = tensor.info()->tensor_shape()[!fortran_order ? j : i];
647 using typestring_type =
typename std::conditional<std::is_floating_point<U>::value, float,
qasymm8_t>
::type;
649 std::vector<typestring_type> tmp;
650 npy::Typestring typestring_o{ tmp };
651 std::string typestring = typestring_o.str();
653 std::ofstream stream(npy_filename, std::ofstream::binary);
654 npy::write_header(stream, typestring, fortran_order,
shape);
663 stream.write(reinterpret_cast<const char *>(in.
ptr()),
sizeof(typestring_type));
670 catch(
const std::ofstream::failure &e)
681 template <
typename T>
690 fs.exceptions(std::ofstream::failbit | std::ofstream::badbit | std::ofstream::eofbit);
692 fs.open(filename, std::ios::in | std::ios::binary);
696 throw std::runtime_error(
"Could not load binary data: " + filename);
706 for(
unsigned int d = 1; d < tensor.info()->num_dimensions(); ++d)
715 fs.read(reinterpret_cast<std::fstream::char_type *>(in.
ptr()), tensor.info()->tensor_shape()[0] * tensor.info()->element_size());
722 catch(
const std::ofstream::failure &e)
728 template <
typename T,
typename TensorType>
736 Iterator it_tensor(&tensor, window);
739 *
reinterpret_cast<T *
>(it_tensor.
ptr()) = value;
746 template <
typename T,
typename TensorType>
752 template <
typename T,
typename TensorType>
763 Iterator it_tensor(&tensor, window);
766 *
reinterpret_cast<T *
>(it_tensor.
ptr()) = vec.at(i++);
773 template <
typename T,
typename TensorType>
776 constexpr
bool is_fp_16bit = std::is_same<T, half>::value || std::is_same<T, bfloat16>::value;
777 constexpr
bool is_integral = std::is_integral<T>::value && !is_fp_16bit;
779 using fp_dist_type =
typename std::conditional<is_fp_16bit, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<T>>
::type;
780 using dist_type =
typename std::conditional<is_integral, std::uniform_int_distribution<T>, fp_dist_type>
::type;
782 std::mt19937 gen(seed);
783 dist_type dist(lower_bound, upper_bound);
793 *
reinterpret_cast<T *
>(it.
ptr()) = dist(gen);
800 template <
typename T,
typename TensorType>
803 std::random_device rd;
807 template <
typename T>
810 dst.allocator()->init(
TensorInfo(
TensorShape(src1.info()->dimension(0), src0.info()->dimension(1), src0.info()->dimension(2)), 1, dt));
826 template <
typename T>
832 int num_mismatches = 0;
839 Iterator itensor1(&tensor1, window);
840 Iterator itensor2(&tensor2, window);
844 if(std::abs(*reinterpret_cast<T *>(itensor1.
ptr()) - *reinterpret_cast<T *>(itensor2.
ptr())) > tolerance)
854 return num_mismatches;
void set(size_t dimension, T value, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
void save_to_ppm(T &tensor, const std::string &ppm_filename)
Template helper function to save a tensor image to a PPM file.
int run_example(int argc, char **argv, std::unique_ptr< Example > example)
Run an example and handle the potential exceptions it throws.
uint64_t get_mem_free_from_meminfo()
This function returns the amount of memory free reading from /proc/meminfo.
quantized, symmetric fixed-point 16-bit number
bool is_fortran()
Return true if a NPY file is in fortran order.
void init_tensor(T &tensor, arm_compute::DataType dt)
Initialise the tensor's metadata with the dimensions of the NPY file currently open.
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
1 channel, 1 U8 per channel
#define ARM_COMPUTE_EXIT_ON_MSG_VAR(cond, msg,...)
If the condition is true, the given message is printed and program exits.
std::string to_string(T &&value)
Convert integer and float values to string.
void fill_tensor(T &tensor)
Fill a tensor with the content of the currently open NPY file.
half_float::half half
16-bit floating point type
1 channel, 1 F32 per channel
Strides PermutationVector
Permutation vector.
#define ARM_COMPUTE_ERROR_VAR(msg,...)
Print the given message then throw an std::runtime_error.
void fill_tensor_value(TensorType &tensor, T value)
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Describe one of the image's dimensions with a start, end and step.
quantized, asymmetric fixed-point 16-bit number
1 channel, 1 U16 per channel
#define ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(t,...)
decltype(strategy::transforms) typedef type
Interface for Neon tensor.
Interface for OpenGL ES tensor.
CLDistribution1D object class.
void use_tensor_dimensions(const TensorShape &shape, size_t first_dimension=Window::DimX)
Use the tensor's dimensions to fill the window dimensions.
SimpleTensor< float > src
Copyright (c) 2017-2021 Arm Limited.
1 channel, 1 F16 per channel
void map(bool blocking=true)
Enqueue a map operation of the allocated buffer.
virtual void do_teardown()
Teardown the example.
void fill_random_tensor(TensorType &tensor, std::random_device::result_type seed, T lower_bound=std::numeric_limits< T >::lowest(), T upper_bound=std::numeric_limits< T >::max())
void permute(Dimensions< T > &dimensions, const PermutationVector &perm)
Permutes given Dimensions according to a permutation vector.
void unmap(T &tensor)
Unmaps a tensor if needed.
1 channel, 1 S32 per channel
3 channels, 1 U8 per channel
std::string get_typestring(DataType data_type)
Obtain numpy type string from DataType.
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t,...)
static constexpr size_t DimX
Alias for dimension 0 also known as X dimension.
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
void save_to_npy(T &tensor, const std::string &npy_filename, bool fortran_order)
Template helper function to save a tensor image to a NPY file.
virtual void do_run()
Run the example.
1 channel, 1 U32 per channel
virtual const TensorShape & tensor_shape() const =0
Size for each dimension of the tensor.
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_DATA_TYPES(...)
quantized, asymmetric fixed-point 8-bit number unsigned
#define ARM_COMPUTE_ERROR_ON_MSG(cond, msg)
NPYLoader()
Default constructor.
#define ARM_COMPUTE_ERROR_ON_MISMATCHING_SHAPES(...)
void map(bool blocking=true)
Enqueue a map operation of the allocated buffer.
std::tuple< std::vector< unsigned long >, bool, std::string > parse_npy_header(std::ifstream &fs)
Parse the npy header from an input file stream.
virtual ITensorInfo * info() const =0
Interface to be implemented by the child class to return the tensor's metadata.
constexpr uint8_t * ptr() const
Return a pointer to the current pixel.
void end(TokenStream &in, bool &valid)
void set(size_t dimension, const Dimension &dim)
Set the values of a given dimension.
std::uniform_real_distribution< float > distribution(-5.f, 5.f)
void unmap()
Enqueue an unmap operation of the allocated and mapped buffer.
bool is_open()
Return true if a NPY file is currently open.
1 channel, 1 S16 per channel
quantized, symmetric fixed-point 8-bit number
Num samples, channels, height, width.
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(t, c,...)
Strides of an item in bytes.
quantized, symmetric per channel fixed-point 8-bit number
void unmap()
Enqueue an unmap operation of the allocated and mapped buffer on the given queue. ...
static constexpr size_t DimY
Alias for dimension 1 also known as Y dimension.
void map(T &tensor, bool blocking)
Maps a tensor if needed.
Detection window used for the object detection.
int compare_tensor(ITensor &tensor1, ITensor &tensor2, T tolerance)
Compare two tensors.
uint8_t qasymm8_t
8 bit quantized asymmetric scalar value
Num samples, height, width, channels.
void draw_detection_rectangle(ITensor *tensor, const DetectionWindow &rect, uint8_t r, uint8_t g, uint8_t b)
Draw a RGB rectangular window for the detected object.
ImageType
Supported image types.
Wrapper to configure the Khronos OpenCL C++ header.
void map(bool blocking=true)
Enqueue a map operation of the allocated buffer on the given queue.
void open(const std::string &npy_filename, DataLayout file_layout=DataLayout::NCHW)
Open a NPY file and reads its metadata.
void fill_tensor_zero(TensorType &tensor)
std::tuple< unsigned int, unsigned int, int > parse_ppm_header(std::ifstream &fs)
Parse the ppm header from an input file stream.
Store the tensor's metadata.
void execute_window_loop(const Window &w, L &&lambda_function, Ts &&... iterators)
Iterate through the passed window, automatically adjusting the iterators and calling the lambda_funct...
ImageType get_image_type_from_file(const std::string &filename)
Gets image type given a file.
void set_num_dimensions(size_t num_dimensions)
Set number of dimensions.
void load_trained_data(T &tensor, const std::string &filename)
Load the tensor with pre-trained data from a binary file.
64-bit floating-point number
Iterator updated by execute_window_loop for each window element.
DataType
Available data types.
void unmap()
Enqueue an unmap operation of the allocated and mapped buffer.
void init_sgemm_output(T &dst, T &src0, T &src1, arm_compute::DataType dt)
DataLayout
[DataLayout enum definition]
Describe a multidimensional execution window.
TensorShape & set(size_t dimension, size_t value, bool apply_dim_correction=true, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
void fill_tensor_vector(TensorType &tensor, std::vector< T > vec)
virtual bool do_setup(int argc, char **argv)
Setup the example.
Basic implementation of the OpenCL tensor interface.