| 216 | } |
| 217 | |
| 218 | PadStrideInfo calculate_same_pad(TensorShape input_shape, |
| 219 | TensorShape weights_shape, |
| 220 | PadStrideInfo conv_info, |
| 221 | DataLayout data_layout, |
| 222 | const Size2D &dilation, |
| 223 | const DimensionRoundingType &rounding_type) |
| 224 | { |
| 225 | const auto &strides = conv_info.stride(); |
| 226 | ARM_COMPUTE_ERROR_ON_MSG((strides.first < 1 || strides.second < 1), |
| 227 | "Stride values should be greater than or equal to 1."); |
| 228 | |
| 229 | const unsigned int width_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH); |
| 230 | const unsigned int height_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT); |
| 231 | const unsigned int in_width = input_shape[width_idx]; |
| 232 | const unsigned int in_height = input_shape[height_idx]; |
| 233 | const unsigned int kernel_width = weights_shape[width_idx]; |
| 234 | const unsigned int kernel_height = weights_shape[height_idx]; |
| 235 | |
| 236 | // Calculate output dimensions |
| 237 | const auto is_ceil = static_cast<unsigned int>(rounding_type == DimensionRoundingType::CEIL); |
| 238 | const unsigned int out_width = ((in_width - is_ceil) + strides.first - 1) / strides.first + is_ceil; |
| 239 | const unsigned int out_height = ((in_height - is_ceil) + strides.second - 1) / strides.second + is_ceil; |
| 240 | |
| 241 | // Calculate effective weights sizes |
| 242 | const int real_weight_width = (kernel_width - 1) * dilation.x() + 1; |
| 243 | const int real_weight_height = (kernel_height - 1) * dilation.y() + 1; |
| 244 | |
| 245 | // Calculate total pad |
| 246 | const int pad_width = std::max(0, static_cast<int>((out_width - 1) * strides.first + real_weight_width - in_width)); |
| 247 | const int pad_height = |
| 248 | std::max(0, static_cast<int>((out_height - 1) * strides.second + real_weight_height - in_height)); |
| 249 | |
| 250 | // Calculate individual paddings |
| 251 | const unsigned int pad_left = pad_width / 2; |
| 252 | const unsigned int pad_top = pad_height / 2; |
| 253 | const unsigned int pad_right = pad_width - pad_left; |
| 254 | const unsigned int pad_bottom = pad_height - pad_top; |
| 255 | |
| 256 | PadStrideInfo same_info(strides.first, strides.second, pad_left, pad_right, pad_top, pad_bottom, rounding_type); |
| 257 | |
| 258 | // Check for correctness of predicted output shape against the one calculated using the generated info |
| 259 | const auto out_dims = scaled_dimensions(in_width, in_height, kernel_width, kernel_height, same_info, dilation); |
| 260 | ARM_COMPUTE_ERROR_ON(out_dims.first != out_width || out_dims.second != out_height); |
| 261 | ARM_COMPUTE_UNUSED(out_dims); |
| 262 | |
| 263 | return same_info; |
| 264 | } |
| 265 | |
| 266 | std::pair<unsigned int, unsigned int> deconvolution_output_dimensions(unsigned int in_width, |
| 267 | unsigned int in_height, |
no test coverage detected