1 /* 2 * Copyright (c) 2017-2023 Arm Limited. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 #ifndef ARM_COMPUTE_SUBTENSORINFO_H 25 #define ARM_COMPUTE_SUBTENSORINFO_H 26 27 #include "arm_compute/core/ITensorInfo.h" 28 29 #include "arm_compute/core/Coordinates.h" 30 #include "arm_compute/core/Helpers.h" 31 #include "arm_compute/core/Strides.h" 32 #include "arm_compute/core/TensorInfo.h" 33 #include "arm_compute/core/TensorShape.h" 34 35 #include <cstddef> 36 #include <memory> 37 38 namespace arm_compute 39 { 40 /** Store the sub tensor's metadata */ 41 class SubTensorInfo final : public ITensorInfo 42 { 43 public: 44 /** Default constructor */ 45 SubTensorInfo(); 46 /** Default constructor 47 * 48 * @param[in] parent Metadata of parent tensor. 49 * @param[in] tensor_shape Tensor shape. Shape must fit inside parent's shape. 50 * X and Y dimensions must match the parent's ones. 51 * @param[in] coords Coordinates of starting element inside parent tensor. 52 * @param[in] extend_parent (Optional) Extend parent with subtensor shape if subtensor indexes out of bounds 53 */ 54 SubTensorInfo(ITensorInfo *parent, TensorShape tensor_shape, Coordinates coords, bool extend_parent = false); 55 /** Default destructor */ 56 ~SubTensorInfo() = default; 57 /** Allow instances of this class to be copy constructed */ 58 SubTensorInfo(const SubTensorInfo &) = default; 59 /** Allow instances of this class to be copied */ 60 SubTensorInfo &operator=(const SubTensorInfo &) = default; 61 /** Allow instances of this class to be move constructed */ 62 SubTensorInfo(SubTensorInfo &&) = default; 63 /** Allow instances of this class to be moved */ 64 SubTensorInfo &operator=(SubTensorInfo &&) = default; 65 /** Returns the coordinates of the sub-tensor inside the parent tensor 66 * 67 * @return Sub-tensor coordinates 68 */ coords()69 Coordinates coords() const 70 { 71 return _coords; 72 } 73 74 // Inherited methods overridden: 75 std::unique_ptr<ITensorInfo> clone() const override; set_data_type(DataType data_type)76 ITensorInfo &set_data_type(DataType data_type) override 77 { 78 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 79 _parent->set_data_type(data_type); 80 return *this; 81 }; set_data_layout(const DataLayout & data_layout)82 ITensorInfo &set_data_layout(const DataLayout &data_layout) override 83 { 84 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 85 _parent->set_data_layout(data_layout); 86 return *this; 87 }; set_num_channels(int num_channels)88 ITensorInfo &set_num_channels(int num_channels) override 89 { 90 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 91 _parent->set_num_channels(num_channels); 92 return *this; 93 }; set_format(Format format)94 ITensorInfo &set_format(Format format) override 95 { 96 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 97 _parent->set_format(format); 98 return *this; 99 }; 100 ITensorInfo &set_tensor_shape(const TensorShape &shape) override; 101 ITensorInfo &set_tensor_dims_state(const TensorDimsState &state) override; set_quantization_info(const QuantizationInfo & quantization_info)102 ITensorInfo &set_quantization_info(const QuantizationInfo &quantization_info) override 103 { 104 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 105 _parent->set_quantization_info(quantization_info); 106 return *this; 107 } reset_padding()108 ITensorInfo &reset_padding() override 109 { 110 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 111 _parent->reset_padding(); 112 return *this; 113 } auto_padding()114 bool auto_padding() override 115 { 116 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 117 return _parent->auto_padding(); 118 }; 119 120 ITensorInfo &set_lock_paddings(bool flag) override; 121 122 bool lock_paddings() const override; 123 124 bool extend_padding(const PaddingSize &padding) override; 125 dimension(size_t index)126 size_t dimension(size_t index) const override 127 { 128 return _tensor_shape[index]; 129 } dimension(DataLayoutDimension dimension)130 size_t dimension(DataLayoutDimension dimension) const override 131 { 132 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 133 return get_data_layout_dimension_index(_parent->data_layout(), dimension); 134 } strides_in_bytes()135 const Strides &strides_in_bytes() const override 136 { 137 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 138 return _parent->strides_in_bytes(); 139 } offset_first_element_in_bytes()140 size_t offset_first_element_in_bytes() const override 141 { 142 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 143 return _parent->offset_element_in_bytes(_coords); 144 } 145 int32_t offset_element_in_bytes(const Coordinates &pos) const override; element_size()146 size_t element_size() const override 147 { 148 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 149 return _parent->element_size(); 150 } num_dimensions()151 size_t num_dimensions() const override 152 { 153 return _tensor_shape.num_dimensions(); 154 } num_channels()155 size_t num_channels() const override 156 { 157 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 158 return _parent->num_channels(); 159 } tensor_shape()160 const TensorShape &tensor_shape() const override 161 { 162 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 163 return _tensor_shape; 164 } tensor_dims_state()165 const TensorDimsState &tensor_dims_state() const override 166 { 167 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 168 return _dims_state; 169 } data_type()170 DataType data_type() const override 171 { 172 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 173 return _parent->data_type(); 174 } format()175 Format format() const override 176 { 177 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 178 return _parent->format(); 179 } total_size()180 size_t total_size() const override 181 { 182 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 183 return _parent->total_size(); 184 } padding()185 PaddingSize padding() const override 186 { 187 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 188 return _parent->padding(); 189 } has_padding()190 bool has_padding() const override 191 { 192 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 193 return _parent->has_padding(); 194 } is_resizable()195 bool is_resizable() const override 196 { 197 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 198 return _parent->is_resizable(); 199 } is_dynamic()200 bool is_dynamic() const override 201 { 202 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 203 return _parent->is_dynamic(); 204 } are_values_constant()205 bool are_values_constant() const override 206 { 207 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 208 return _parent->are_values_constant(); 209 } set_is_resizable(bool is_resizable)210 ITensorInfo &set_is_resizable(bool is_resizable) override 211 { 212 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 213 _parent->set_is_resizable(is_resizable); 214 return *this; 215 } set_are_values_constant(bool are_values_constant)216 ITensorInfo &set_are_values_constant(bool are_values_constant) override 217 { 218 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 219 _parent->set_are_values_constant(are_values_constant); 220 return *this; 221 } valid_region()222 ValidRegion valid_region() const override 223 { 224 return _valid_region; 225 } set_valid_region(const ValidRegion & valid_region)226 void set_valid_region(const ValidRegion &valid_region) override 227 { 228 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 229 // Check if subtensor is valid if parent is configured 230 if(_parent->tensor_shape().total_size() != 0) 231 { 232 ARM_COMPUTE_ERROR_ON_INVALID_SUBTENSOR_VALID_REGION(_parent->valid_region(), valid_region); 233 } 234 _valid_region = valid_region; 235 } quantization_info()236 QuantizationInfo quantization_info() const override 237 { 238 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 239 return _parent->quantization_info(); 240 } data_layout()241 DataLayout data_layout() const override 242 { 243 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 244 return _parent->data_layout(); 245 } id()246 ITensorInfo::Id id() const override 247 { 248 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 249 return _parent->id(); 250 } set_id(ITensorInfo::Id id)251 ITensorInfo &set_id(ITensorInfo::Id id) override 252 { 253 ARM_COMPUTE_ERROR_ON(_parent == nullptr); 254 _parent->set_id(id); 255 return *this; 256 } 257 258 private: 259 ITensorInfo *_parent; 260 TensorShape _tensor_shape; 261 TensorDimsState _dims_state; 262 Coordinates _coords; 263 ValidRegion _valid_region; 264 bool _extend_parent; 265 bool _lock_paddings; 266 }; 267 } // namespace arm_compute 268 #endif /*ARM_COMPUTE_SUBTENSORINFO_H */ 269