Compute Library
 21.02
NPYLoader Class Reference

Numpy data loader. More...

#include <Utils.h>

Public Member Functions

 NPYLoader ()
 Default constructor. More...
 
void open (const std::string &npy_filename, DataLayout file_layout=DataLayout::NCHW)
 Open a NPY file and reads its metadata. More...
 
bool is_open ()
 Return true if a NPY file is currently open. More...
 
bool is_fortran ()
 Return true if a NPY file is in fortran order. More...
 
template<typename T >
void init_tensor (T &tensor, arm_compute::DataType dt)
 Initialise the tensor's metadata with the dimensions of the NPY file currently open. More...
 
template<typename T >
void fill_tensor (T &tensor)
 Fill a tensor with the content of the currently open NPY file. More...
 

Detailed Description

Numpy data loader.

Definition at line 328 of file Utils.h.

Constructor & Destructor Documentation

◆ NPYLoader()

NPYLoader ( )
inline

Default constructor.

Definition at line 332 of file Utils.h.

References arm_compute::NCHW.

333  : _fs(), _shape(), _fortran_order(false), _typestring(), _file_layout(DataLayout::NCHW)
334  {
335  }
Num samples, channels, height, width.

Member Function Documentation

◆ fill_tensor()

void fill_tensor ( T &  tensor)
inline

Fill a tensor with the content of the currently open NPY file.

Note
If the tensor is a CLTensor, the function maps and unmaps the tensor
Parameters
[in,out]tensorTensor to fill (Must be allocated, and of matching dimensions with the opened NPY).

Definition at line 406 of file Utils.h.

References ARM_COMPUTE_ERROR, ARM_COMPUTE_ERROR_ON, ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN, ARM_COMPUTE_ERROR_ON_MSG, ARM_COMPUTE_ERROR_VAR, ARM_COMPUTE_UNUSED, arm_compute::test::validation::dst, arm_compute::mlgo::parser::end(), arm_compute::execute_window_loop(), arm_compute::F16, arm_compute::F32, arm_compute::utils::get_typestring(), arm_compute::utils::map(), arm_compute::NCHW, arm_compute::NHWC, arm_compute::permute(), arm_compute::QASYMM8, arm_compute::S32, Dimensions< T >::set(), TensorShape::set(), arm_compute::utils::cast::U, arm_compute::utils::unmap(), and Window::use_tensor_dimensions().

Referenced by NumPyBinLoader::access_tensor().

407  {
410  try
411  {
412  // Map buffer if creating a CLTensor
413  map(tensor, true);
414 
415  // Check if the file is large enough to fill the tensor
416  const size_t current_position = _fs.tellg();
417  _fs.seekg(0, std::ios_base::end);
418  const size_t end_position = _fs.tellg();
419  _fs.seekg(current_position, std::ios_base::beg);
420 
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");
423  ARM_COMPUTE_UNUSED(end_position);
424 
425  // Check if the typestring matches the given one
426  std::string expect_typestr = get_typestring(tensor.info()->data_type());
427  ARM_COMPUTE_ERROR_ON_MSG(_typestring != expect_typestr, "Typestrings mismatch");
428 
429  bool are_layouts_different = (_file_layout != tensor.info()->data_layout());
430  // Correct dimensions (Needs to match TensorShape dimension corrections)
431  if(_shape.size() != tensor.info()->tensor_shape().num_dimensions())
432  {
433  for(int i = static_cast<int>(_shape.size()) - 1; i > 0; --i)
434  {
435  if(_shape[i] == 1)
436  {
437  _shape.pop_back();
438  }
439  else
440  {
441  break;
442  }
443  }
444  }
445 
446  TensorShape permuted_shape = tensor.info()->tensor_shape();
448  if(are_layouts_different && tensor.info()->tensor_shape().num_dimensions() > 2)
449  {
450  perm = (tensor.info()->data_layout() == arm_compute::DataLayout::NHWC) ? arm_compute::PermutationVector(2U, 0U, 1U) : arm_compute::PermutationVector(1U, 2U, 0U);
451  arm_compute::PermutationVector perm_vec = (tensor.info()->data_layout() == arm_compute::DataLayout::NCHW) ? arm_compute::PermutationVector(2U, 0U, 1U) : arm_compute::PermutationVector(1U, 2U, 0U);
452 
453  arm_compute::permute(permuted_shape, perm_vec);
454  }
455 
456  // Validate tensor shape
457  ARM_COMPUTE_ERROR_ON_MSG(_shape.size() != tensor.info()->tensor_shape().num_dimensions(), "Tensor ranks mismatch");
458  for(size_t i = 0; i < _shape.size(); ++i)
459  {
460  ARM_COMPUTE_ERROR_ON_MSG(permuted_shape[i] != _shape[i], "Tensor dimensions mismatch");
461  }
462 
463  switch(tensor.info()->data_type())
464  {
469  {
470  // Read data
471  if(!are_layouts_different && !_fortran_order && tensor.info()->padding().empty())
472  {
473  // If tensor has no padding read directly from stream.
474  _fs.read(reinterpret_cast<char *>(tensor.buffer()), tensor.info()->total_size());
475  }
476  else
477  {
478  // If tensor has padding or is in fortran order accessing tensor elements through execution window.
479  Window window;
480  const unsigned int num_dims = _shape.size();
481  if(_fortran_order)
482  {
483  for(unsigned int dim = 0; dim < num_dims; dim++)
484  {
485  permuted_shape.set(dim, _shape[num_dims - dim - 1]);
486  perm.set(dim, num_dims - dim - 1);
487  }
488  if(are_layouts_different)
489  {
490  // Permute only if num_dimensions greater than 2
491  if(num_dims > 2)
492  {
493  if(_file_layout == DataLayout::NHWC) // i.e destination is NCHW --> permute(1,2,0)
494  {
496  }
497  else
498  {
500  }
501  }
502  }
503  }
504  window.use_tensor_dimensions(permuted_shape);
505 
506  execute_window_loop(window, [&](const Coordinates & id)
507  {
508  Coordinates dst(id);
509  arm_compute::permute(dst, perm);
510  _fs.read(reinterpret_cast<char *>(tensor.ptr_to_element(dst)), tensor.info()->element_size());
511  });
512  }
513 
514  break;
515  }
516  default:
517  ARM_COMPUTE_ERROR("Unsupported data type");
518  }
519 
520  // Unmap buffer if creating a CLTensor
521  unmap(tensor);
522  }
523  catch(const std::ifstream::failure &e)
524  {
525  ARM_COMPUTE_ERROR_VAR("Loading NPY file: %s", e.what());
526  }
527  }
void set(size_t dimension, T value, bool increase_dim_unit=true)
Accessor to set the value of one of the dimensions.
Definition: Dimensions.h:76
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:352
1 channel, 1 F32 per channel
Strides PermutationVector
Permutation vector.
Definition: Types.h:49
#define ARM_COMPUTE_ERROR_VAR(msg,...)
Print the given message then throw an std::runtime_error.
Definition: Error.h:346
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
1 channel, 1 F16 per channel
void permute(Dimensions< T > &dimensions, const PermutationVector &perm)
Permutes given Dimensions according to a permutation vector.
Definition: Helpers.h:125
void unmap(T &tensor)
Unmaps a tensor if needed.
Definition: Utils.h:227
1 channel, 1 S32 per channel
std::string get_typestring(DataType data_type)
Obtain numpy type string from DataType.
Definition: Utils.h:158
#define ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(t,...)
Definition: Validate.h:692
#define ARM_COMPUTE_UNUSED(...)
To avoid unused variables warnings.
Definition: Error.h:152
quantized, asymmetric fixed-point 8-bit number unsigned
#define ARM_COMPUTE_ERROR_ON_MSG(cond, msg)
Definition: Error.h:456
void end(TokenStream &in, bool &valid)
Definition: MLGOParser.cpp:290
bool is_open()
Return true if a NPY file is currently open.
Definition: Utils.h:360
Num samples, channels, height, width.
Strides of an item in bytes.
Definition: Strides.h:37
void map(T &tensor, bool blocking)
Maps a tensor if needed.
Definition: Utils.h:216
Num samples, height, width, channels.
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...
Definition: Helpers.inl:77

◆ init_tensor()

void init_tensor ( T &  tensor,
arm_compute::DataType  dt 
)
inline

Initialise the tensor's metadata with the dimensions of the NPY file currently open.

Parameters
[out]tensorTensor to initialise
[in]dtData type to use for the tensor

Definition at line 377 of file Utils.h.

References ARM_COMPUTE_ERROR_ON, arm_compute::F32, TensorShape::set(), Dimensions< T >::set_num_dimensions(), arm_compute::test::validation::shape, and arm_compute::test::validation::src.

378  {
381 
382  // Use the size of the input NPY tensor
383  TensorShape shape;
384  shape.set_num_dimensions(_shape.size());
385  for(size_t i = 0; i < _shape.size(); ++i)
386  {
387  size_t src = i;
388  if(_fortran_order)
389  {
390  src = _shape.size() - 1 - i;
391  }
392  shape.set(i, _shape.at(src));
393  }
394 
395  arm_compute::TensorInfo tensor_info(shape, 1, dt);
396  tensor.allocator()->init(tensor_info);
397  }
1 channel, 1 F32 per channel
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
SimpleTensor< float > src
Definition: DFT.cpp:155
DataType dt
bool is_open()
Return true if a NPY file is currently open.
Definition: Utils.h:360
Store the tensor&#39;s metadata.
Definition: TensorInfo.h:45

◆ is_fortran()

bool is_fortran ( )
inline

Return true if a NPY file is in fortran order.

Definition at line 366 of file Utils.h.

367  {
368  return _fortran_order;
369  }

◆ is_open()

bool is_open ( )
inline

Return true if a NPY file is currently open.

Definition at line 360 of file Utils.h.

361  {
362  return _fs.is_open();
363  }

◆ open()

void open ( const std::string &  npy_filename,
DataLayout  file_layout = DataLayout::NCHW 
)
inline

Open a NPY file and reads its metadata.

Parameters
[in]npy_filenameFile to open
[in]file_layout(Optional) Layout in which the weights are stored in the file.

Definition at line 342 of file Utils.h.

References ARM_COMPUTE_ERROR_ON, ARM_COMPUTE_ERROR_VAR, ARM_COMPUTE_EXIT_ON_MSG_VAR, and arm_compute::utils::parse_npy_header().

Referenced by NumPyBinLoader::access_tensor().

343  {
345  try
346  {
347  _fs.open(npy_filename, std::ios::in | std::ios::binary);
348  ARM_COMPUTE_EXIT_ON_MSG_VAR(!_fs.good(), "Failed to load binary data from %s", npy_filename.c_str());
349  _fs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
350  _file_layout = file_layout;
351 
352  std::tie(_shape, _fortran_order, _typestring) = parse_npy_header(_fs);
353  }
354  catch(const std::ifstream::failure &e)
355  {
356  ARM_COMPUTE_ERROR_VAR("Accessing %s: %s", npy_filename.c_str(), e.what());
357  }
358  }
#define ARM_COMPUTE_EXIT_ON_MSG_VAR(cond, msg,...)
If the condition is true, the given message is printed and program exits.
Definition: Error.h:395
#define ARM_COMPUTE_ERROR_VAR(msg,...)
Print the given message then throw an std::runtime_error.
Definition: Error.h:346
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
std::tuple< std::vector< unsigned long >, bool, std::string > parse_npy_header(std::ifstream &fs)
Parse the npy header from an input file stream.
Definition: Utils.cpp:233
bool is_open()
Return true if a NPY file is currently open.
Definition: Utils.h:360

The documentation for this class was generated from the following file: