From d17a677a70d477ae508c084148ba6974fc38477d Mon Sep 17 00:00:00 2001 From: Isabella Gottardi Date: Tue, 27 Feb 2018 17:41:55 +0000 Subject: COMPMID-979: Add NHWC data layout to the tensor's metadata Change-Id: I89bdab7dc63a437eb7d60c0ae652c53c3875e503 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/122524 Tested-by: Jenkins Reviewed-by: Anthony Barbier Reviewed-by: Pablo Tello --- arm_compute/core/Helpers.h | 19 +++++++++++++++++++ arm_compute/core/Helpers.inl | 41 ++++++++++++++++++++++++++++++++++++++++ arm_compute/core/ITensorInfo.h | 12 ++++++++++++ arm_compute/core/SubTensorInfo.h | 11 +++++++++++ arm_compute/core/TensorInfo.h | 6 ++++++ arm_compute/core/Types.h | 10 ++++++++++ src/core/TensorInfo.cpp | 9 ++++++++- 7 files changed, 107 insertions(+), 1 deletion(-) diff --git a/arm_compute/core/Helpers.h b/arm_compute/core/Helpers.h index 63fad1dcea..c91299f218 100644 --- a/arm_compute/core/Helpers.h +++ b/arm_compute/core/Helpers.h @@ -588,6 +588,16 @@ bool set_format_if_unknown(ITensorInfo &info, Format format); */ bool set_data_type_if_unknown(ITensorInfo &info, DataType data_type); +/* Set the data layout to the specified value if + * the current data layout is unknown. + * + * @param[in,out] info Tensor info used to check and assign. + * @param[in] data_layout New data layout. + * + * @return True if the data type has been changed. + */ +bool set_data_layout_if_unknown(ITensorInfo &info, DataLayout data_layout); + /* Set the fixed point position to the specified value if * the current fixed point position is 0 and the data type is QS8 or QS16 * @@ -637,6 +647,15 @@ inline Coordinates index2coords(const TensorShape &shape, int index); * @return linead index */ inline int coords2index(const TensorShape &shape, const Coordinates &coord); + +/* Get the index of the given dimension. + * + * @param[in] info Tensor info used to check and assign. + * @param[in] data_layout New data layout. + * + * @return The int conversion of the requested data layout index. + */ +inline int get_data_layout_dimension_index(const ITensorInfo &info, const DataLayoutDimension data_layout_dimension); } // namespace arm_compute #include "arm_compute/core/Helpers.inl" diff --git a/arm_compute/core/Helpers.inl b/arm_compute/core/Helpers.inl index 8b86c22676..ff85773abb 100644 --- a/arm_compute/core/Helpers.inl +++ b/arm_compute/core/Helpers.inl @@ -227,6 +227,7 @@ inline bool auto_init_if_empty(ITensorInfo &info_sink, const ITensorInfo &info_s info_sink.set_tensor_shape(info_source.tensor_shape()); info_sink.set_fixed_point_position(info_source.fixed_point_position()); info_sink.set_quantization_info(info_source.quantization_info()); + info_sink.set_data_layout(info_source.data_layout()); return true; } @@ -266,6 +267,17 @@ inline bool set_data_type_if_unknown(ITensorInfo &info, DataType data_type) return false; } +inline bool set_data_layout_if_unknown(ITensorInfo &info, DataLayout data_layout) +{ + if(info.data_layout() == DataLayout::UNKNOWN) + { + info.set_data_layout(data_layout); + return true; + } + + return false; +} + inline bool set_fixed_point_position_if_zero(ITensorInfo &info, int fixed_point_position) { if(info.fixed_point_position() == 0 && (info.data_type() == DataType::QS8 || info.data_type() == DataType::QS16)) @@ -357,4 +369,33 @@ inline int coords2index(const TensorShape &shape, const Coordinates &coord) return index; } + +inline int get_data_layout_dimension_index(const ITensorInfo &info, const DataLayoutDimension data_layout_dimension) +{ + ARM_COMPUTE_ERROR_ON_MSG(info.data_layout() == DataLayout::UNKNOWN, "Cannot retrieve the dimension index for an unknown layout!"); + + /* Return the index based on the data layout + * [N C H W] + * [3 2 1 0] + * [N H W C] + */ + switch(data_layout_dimension) + { + case DataLayoutDimension::CHANNEL: + return (info.data_layout() == DataLayout::NCHW) ? 2 : 0; + break; + case DataLayoutDimension::HEIGHT: + return (info.data_layout() == DataLayout::NCHW) ? 1 : 2; + break; + case DataLayoutDimension::WIDTH: + return (info.data_layout() == DataLayout::NCHW) ? 0 : 1; + break; + case DataLayoutDimension::BATCHES: + return 3; + break; + default: + ARM_COMPUTE_ERROR("Data layout index not supported!"); + break; + } +} } // namespace arm_compute diff --git a/arm_compute/core/ITensorInfo.h b/arm_compute/core/ITensorInfo.h index b5677dffd6..50a1eb2ff1 100644 --- a/arm_compute/core/ITensorInfo.h +++ b/arm_compute/core/ITensorInfo.h @@ -97,6 +97,13 @@ public: * @return Reference to this ITensorInfo object */ virtual ITensorInfo &set_quantization_info(const QuantizationInfo &quantization_info) = 0; + /** Set the data layout of the tensor. + * + * @param[in] data_layout DataLayout containing the layout data information. + * + * @return Reference to this ITensorInfo object + */ + virtual ITensorInfo &set_data_layout(const DataLayout &data_layout) = 0; /** Resets the padding settings of the tensor. * * @return Reference to this ITensorInfo object @@ -222,6 +229,11 @@ public: * @return A QuantizationInfo containing the scale and offset. */ virtual QuantizationInfo quantization_info() const = 0; + /** Get the data layout of the tensor. + * + * @return A DataLayout containing the layout data information. + */ + virtual DataLayout data_layout() const = 0; /** If infos are broadcast compatible tensor info's, return the broadcasted shape and the intersection of * the broadcasted valid regions of the tensors. diff --git a/arm_compute/core/SubTensorInfo.h b/arm_compute/core/SubTensorInfo.h index 7f4239d49b..f9ed99b308 100644 --- a/arm_compute/core/SubTensorInfo.h +++ b/arm_compute/core/SubTensorInfo.h @@ -80,6 +80,12 @@ public: _parent->set_data_type(data_type); return *this; }; + ITensorInfo &set_data_layout(const DataLayout &data_layout) override + { + ARM_COMPUTE_ERROR_ON(_parent == nullptr); + _parent->set_data_layout(data_layout); + return *this; + }; ITensorInfo &set_num_channels(int num_channels) override { ARM_COMPUTE_ERROR_ON(_parent == nullptr); @@ -211,6 +217,11 @@ public: ARM_COMPUTE_ERROR_ON(_parent == nullptr); return _parent->quantization_info(); } + DataLayout data_layout() const override + { + ARM_COMPUTE_ERROR_ON(_parent == nullptr); + return _parent->data_layout(); + } private: ITensorInfo *_parent; diff --git a/arm_compute/core/TensorInfo.h b/arm_compute/core/TensorInfo.h index 0b8989f942..27cf5bae82 100644 --- a/arm_compute/core/TensorInfo.h +++ b/arm_compute/core/TensorInfo.h @@ -220,6 +220,7 @@ public: ITensorInfo &set_tensor_shape(const TensorShape &shape) override; ITensorInfo &set_fixed_point_position(int fixed_point_position) override; ITensorInfo &set_quantization_info(const QuantizationInfo &quantization_info) override; + ITensorInfo &set_data_layout(const DataLayout &data_layout) override; ITensorInfo &reset_padding() override; bool auto_padding() override; bool extend_padding(const PaddingSize &padding) override; @@ -297,6 +298,10 @@ public: { return _quantization_info; } + DataLayout data_layout() const override + { + return _data_layout; + } private: /** Calculates strides, offset and total size resulting from the specified padding around the XY plane. @@ -317,6 +322,7 @@ private: ValidRegion _valid_region; PaddingSize _padding; QuantizationInfo _quantization_info; + DataLayout _data_layout; }; } #endif /*__ARM_COMPUTE_TENSORINFO_H__ */ diff --git a/arm_compute/core/Types.h b/arm_compute/core/Types.h index 24c73ca7c1..143ee025f5 100644 --- a/arm_compute/core/Types.h +++ b/arm_compute/core/Types.h @@ -109,10 +109,20 @@ constexpr float SCALE_PYRAMID_ORB = 8.408964152537146130583778358414e-01; /** Supported tensor data layouts */ enum class DataLayout { + UNKNOWN, NCHW, NHWC }; +/** Supported tensor data layout dimensions */ +enum class DataLayoutDimension +{ + CHANNEL, + HEIGHT, + WIDTH, + BATCHES +}; + /** Quantization settings (used for QASYMM8 data type) */ struct QuantizationInfo { diff --git a/src/core/TensorInfo.cpp b/src/core/TensorInfo.cpp index bd0c85f3d4..2190e3415c 100644 --- a/src/core/TensorInfo.cpp +++ b/src/core/TensorInfo.cpp @@ -34,7 +34,7 @@ using namespace arm_compute; TensorInfo::TensorInfo() : _total_size(0), _fixed_point_position(0), _offset_first_element_in_bytes(0), _strides_in_bytes(), _num_channels(0), _tensor_shape(), _data_type(DataType::UNKNOWN), _format(Format::UNKNOWN), - _is_resizable{ true }, _valid_region{ Coordinates(), _tensor_shape }, _padding{ 0 }, _quantization_info() + _is_resizable{ true }, _valid_region{ Coordinates(), _tensor_shape }, _padding{ 0 }, _quantization_info(), _data_layout(DataLayout::NCHW) { } @@ -53,6 +53,7 @@ TensorInfo::TensorInfo(const ITensorInfo &info) _valid_region = info.valid_region(); _padding = info.padding(); _quantization_info = info.quantization_info(); + _data_layout = info.data_layout(); } TensorInfo::TensorInfo(Format format) @@ -384,6 +385,12 @@ ITensorInfo &TensorInfo::set_quantization_info(const QuantizationInfo &quantizat return *this; } +ITensorInfo &TensorInfo::set_data_layout(const DataLayout &data_layout) +{ + _data_layout = data_layout; + return *this; +} + ITensorInfo &TensorInfo::reset_padding() { _padding = PaddingSize(); -- cgit v1.2.1