diff options
author | Anthony Barbier <anthony.barbier@arm.com> | 2017-09-04 18:44:23 +0100 |
---|---|---|
committer | Anthony Barbier <anthony.barbier@arm.com> | 2018-09-17 13:03:09 +0100 |
commit | 6ff3b19ee6120edf015fad8caab2991faa3070af (patch) | |
tree | a7a6dcd16dfd56d79fa1b56a313caeebcc939b68 /src/core/TensorInfo.cpp | |
download | ComputeLibrary-6ff3b19ee6120edf015fad8caab2991faa3070af.tar.gz |
COMPMID-344 Updated doxygen
Change-Id: I32f7b84daa560e460b77216add529c8fa8b327ae
Diffstat (limited to 'src/core/TensorInfo.cpp')
-rw-r--r-- | src/core/TensorInfo.cpp | 377 |
1 files changed, 377 insertions, 0 deletions
diff --git a/src/core/TensorInfo.cpp b/src/core/TensorInfo.cpp new file mode 100644 index 0000000000..3d07ccb69a --- /dev/null +++ b/src/core/TensorInfo.cpp @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2016, 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "arm_compute/core/TensorInfo.h" + +#include "arm_compute/core/Error.h" +#include "arm_compute/core/HOGInfo.h" +#include "arm_compute/core/Helpers.h" +#include "arm_compute/core/Validate.h" + +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 } +{ +} + +TensorInfo::TensorInfo(const ITensorInfo &info) + : TensorInfo() +{ + _total_size = info.total_size(); + _fixed_point_position = info.fixed_point_position(); + _offset_first_element_in_bytes = info.offset_first_element_in_bytes(); + _strides_in_bytes = info.strides_in_bytes(); + _num_channels = info.num_channels(); + _tensor_shape = info.tensor_shape(); + _data_type = info.data_type(); + _format = info.format(); + _is_resizable = info.is_resizable(); + _valid_region = info.valid_region(); + _padding = info.padding(); +} + +TensorInfo::TensorInfo(Format format) + : TensorInfo(TensorShape(), format) +{ +} + +TensorInfo::TensorInfo(unsigned int width, unsigned int height, Format format) + : TensorInfo(TensorShape(width, height), format) +{ +} + +TensorInfo::TensorInfo(const TensorShape &tensor_shape, Format format) + : TensorInfo() +{ + init(tensor_shape, format); +} + +TensorInfo::TensorInfo(size_t num_channels, DataType data_type, size_t fixed_point_position) + : TensorInfo() +{ + init(TensorShape(), num_channels, data_type, fixed_point_position); +} + +TensorInfo::TensorInfo(const TensorShape &tensor_shape, size_t num_channels, DataType data_type, int fixed_point_position) + : TensorInfo() +{ + init(tensor_shape, num_channels, data_type, fixed_point_position); +} + +TensorInfo::TensorInfo(const HOGInfo &hog_info, unsigned int width, unsigned int height) + : TensorInfo() +{ + init(hog_info, width, height); +} + +void TensorInfo::init(Format format) +{ + init(TensorShape(), format); +} + +void TensorInfo::init(const TensorShape &tensor_shape, Format format) +{ + size_t num_channels = num_channels_from_format(format); + const DataType type = data_type_from_format(format); + + init(tensor_shape, num_channels, type); + + _format = format; +} + +void TensorInfo::init(const TensorShape &tensor_shape, Format format, + const Strides &strides_in_bytes, size_t offset_first_element_in_bytes, + size_t total_size_in_bytes) +{ + size_t num_channels = num_channels_from_format(format); + const DataType type = data_type_from_format(format); + + init(tensor_shape, num_channels, type, strides_in_bytes, offset_first_element_in_bytes, total_size_in_bytes); + + _format = format; +} + +void TensorInfo::init(size_t num_channels, DataType data_type, size_t fixed_point_position) +{ + init(TensorShape(), num_channels, data_type, fixed_point_position); +} + +void TensorInfo::init(const TensorShape &tensor_shape, size_t num_channels, DataType data_type, int fixed_point_position) +{ + ARM_COMPUTE_ERROR_ON(num_channels == 0); + ARM_COMPUTE_ERROR_ON(data_type == DataType::QS8 && (fixed_point_position < 1 || fixed_point_position > 6)); + ARM_COMPUTE_ERROR_ON(data_type == DataType::QS16 && (fixed_point_position < 1 || fixed_point_position > 14)); + + _fixed_point_position = fixed_point_position; + _data_type = data_type; + _num_channels = num_channels; + _format = Format::UNKNOWN; + + set_tensor_shape(tensor_shape); +} + +void TensorInfo::init(const TensorShape &tensor_shape, size_t num_channels, DataType data_type, + const Strides &strides_in_bytes, size_t offset_first_element_in_bytes, + size_t total_size_in_bytes, int fixed_point_position) +{ + ARM_COMPUTE_ERROR_ON(num_channels == 0); + ARM_COMPUTE_ERROR_ON(data_type == DataType::QS8 && (fixed_point_position < 1 || fixed_point_position > 6)); + ARM_COMPUTE_ERROR_ON(data_type == DataType::QS16 && (fixed_point_position < 1 || fixed_point_position > 14)); + + _fixed_point_position = fixed_point_position; + _data_type = data_type; + _num_channels = num_channels; + _format = Format::UNKNOWN; + _tensor_shape = tensor_shape; + _offset_first_element_in_bytes = offset_first_element_in_bytes; + _strides_in_bytes = strides_in_bytes; + _total_size = total_size_in_bytes; + + Coordinates coordinates; + coordinates.set_num_dimensions(_tensor_shape.num_dimensions()); + _valid_region = ValidRegion{ coordinates, _tensor_shape }; +} + +void TensorInfo::init(const HOGInfo &hog_info, unsigned int width, unsigned int height) +{ + // Number of cells for each block + const Size2D num_cells_per_block = hog_info.num_cells_per_block(); + + // Tensor Size = (Number of horizontal blocks) * (Number of vertical blocks ) + const Size2D num_blocks_per_img = hog_info.num_blocks_per_image(Size2D(width, height)); + + // Number of tensor channels = (Number of cells per block) * (Number of bins per cell) + const size_t num_channels = num_cells_per_block.area() * hog_info.num_bins(); + + init(TensorShape(num_blocks_per_img.width, num_blocks_per_img.height), num_channels, DataType::F32); +} + +size_t TensorInfo::init_auto_padding(const TensorShape &tensor_shape, Format format) +{ + const size_t num_channels = num_channels_from_format(format); + const DataType type = data_type_from_format(format); + size_t total_size = init_auto_padding(tensor_shape, num_channels, type); + + _format = format; + + return total_size; +} + +size_t TensorInfo::init_auto_padding(const TensorShape &tensor_shape, size_t num_channels, DataType data_type, int fixed_point_position) +{ + ARM_COMPUTE_ERROR_ON(num_channels == 0); + ARM_COMPUTE_ERROR_ON(data_type == DataType::QS8 && (fixed_point_position < 1 || fixed_point_position > 6)); + ARM_COMPUTE_ERROR_ON(data_type == DataType::QS16 && (fixed_point_position < 1 || fixed_point_position > 14)); + + _fixed_point_position = fixed_point_position; + _data_type = data_type; + _num_channels = num_channels; + _format = Format::UNKNOWN; + _tensor_shape = tensor_shape; + + Coordinates coordinates; + coordinates.set_num_dimensions(_tensor_shape.num_dimensions()); + _valid_region = ValidRegion{ coordinates, _tensor_shape }; + + auto_padding(); + + return _total_size; +} + +size_t TensorInfo::init_auto_padding(const HOGInfo &hog_info, unsigned int width, unsigned int height) +{ + // Number of cells for each block + const Size2D num_cells_per_block = hog_info.num_cells_per_block(); + + // Tensor Size = (Number of horizontal blocks) * (Number of vertical blocks ) + const Size2D num_blocks_per_img = hog_info.num_blocks_per_image(Size2D(width, height)); + + // Number of tensor channels = (Number of cells per block) * (Number of bins per cell) + const size_t num_channels = num_cells_per_block.area() * hog_info.num_bins(); + + return init_auto_padding(TensorShape(num_blocks_per_img.width, num_blocks_per_img.height), num_channels, DataType::F32); +} + +bool TensorInfo::auto_padding() +{ + ARM_COMPUTE_ERROR_ON(!_is_resizable); + + // Some kernels compute 32 elements at the time, worst case scenario they + // will read 32 values after the last element + const size_t extra_pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 32; + const size_t pad_x = _tensor_shape.num_dimensions() < 1 ? 0 : 4; + const size_t pad_y = _tensor_shape.num_dimensions() < 2 ? 0 : 4; + + return extend_padding(PaddingSize(pad_y, pad_x + extra_pad_x, pad_y, pad_x)); +} + +std::tuple<Strides, size_t, size_t> TensorInfo::calculate_padding_requirements(const PaddingSize &padding) +{ + // Calculate resulting stride for the X, Y and Z dimension + const size_t stride_x = element_size(); + const size_t stride_y = (padding.left + _tensor_shape[0] + padding.right) * stride_x; + const size_t stride_z = (padding.top + _tensor_shape[1] + padding.bottom) * stride_y; + + Strides required_strides; + size_t required_total_size = 0; + const size_t required_offset_first_element = padding.left * stride_x + padding.top * stride_y; + + switch(_tensor_shape.num_dimensions()) + { + case 0: + { + if(_tensor_shape.total_size() > 0) + { + required_strides = Strides(stride_x); + required_total_size = stride_z; + } + break; + } + case 1: + required_strides = compute_strides(*this, stride_x); + required_total_size = stride_z; + break; + case 2: + required_strides = compute_strides(*this, stride_x, stride_y); + required_total_size = stride_z; + break; + default: + { + required_strides = compute_strides(*this, stride_x, stride_y, stride_z); + + const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1; + + required_total_size = _tensor_shape[idx_last_dimension] * required_strides[idx_last_dimension]; + break; + } + } + + return std::make_tuple(required_strides, required_offset_first_element, required_total_size); +} + +bool TensorInfo::extend_padding(const PaddingSize &padding) +{ + ARM_COMPUTE_ERROR_ON(!_is_resizable); + + bool updated = false; + + if(padding.top > _padding.top) + { + _padding.top = padding.top; + updated = true; + } + + if(padding.right > _padding.right) + { + _padding.right = padding.right; + updated = true; + } + + if(padding.bottom > _padding.bottom) + { + _padding.bottom = padding.bottom; + updated = true; + } + + if(padding.left > _padding.left) + { + _padding.left = padding.left; + updated = true; + } + + std::tie(_strides_in_bytes, _offset_first_element_in_bytes, _total_size) = calculate_padding_requirements(_padding); + + return updated; +} + +void TensorInfo::set_data_type(DataType data_type) +{ + _data_type = data_type; + _format = Format::UNKNOWN; +} + +void TensorInfo::set_num_channels(int num_channels) +{ + _num_channels = num_channels; + _format = Format::UNKNOWN; +} + +void TensorInfo::set_format(Format format) +{ + _format = format; + + if(_data_type == DataType::UNKNOWN) + { + _num_channels = num_channels_from_format(format); + _data_type = data_type_from_format(format); + } + else + { + ARM_COMPUTE_ERROR_ON(num_channels_from_format(format) != _num_channels); + ARM_COMPUTE_ERROR_ON(data_type_from_format(format) != _data_type); + } +} + +void TensorInfo::set_tensor_shape(TensorShape shape) +{ + _tensor_shape = shape; + _offset_first_element_in_bytes = 0; + _strides_in_bytes = compute_strides(*this); + + if(_tensor_shape.num_dimensions() == 0) + { + _total_size = _strides_in_bytes[0]; + } + else + { + const unsigned int idx_last_dimension = _tensor_shape.num_dimensions() - 1; + _total_size = _tensor_shape[idx_last_dimension] * _strides_in_bytes[idx_last_dimension]; + } + + Coordinates coordinates; + coordinates.set_num_dimensions(_tensor_shape.num_dimensions()); + _valid_region = ValidRegion{ coordinates, _tensor_shape }; +} + +void TensorInfo::set_fixed_point_position(int fixed_point_position) +{ + ARM_COMPUTE_ERROR_ON(_data_type == DataType::QS8 && (fixed_point_position < 1 || fixed_point_position > 6)); + ARM_COMPUTE_ERROR_ON(_data_type == DataType::QS16 && (fixed_point_position < 1 || fixed_point_position > 14)); + _fixed_point_position = fixed_point_position; +} + +size_t TensorInfo::offset_element_in_bytes(const Coordinates &pos) const +{ + ARM_COMPUTE_ERROR_ON_COORDINATES_DIMENSIONS_GTE(pos, _tensor_shape.num_dimensions()); + + size_t offset = _offset_first_element_in_bytes; + + for(size_t i = 0; i < _tensor_shape.num_dimensions(); ++i) + { + offset += pos[i] * _strides_in_bytes[i]; + } + + return offset; +} |