// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include "paddle/phi/core/ddim.h" namespace phi { template inline void UpdatePaddingAndDilation(std::vector* paddings, std::vector* dilation, const std::string padding_algorithm, const DDim data_dims, const std::vector& strides, const std::vector& ksize) { // set padding size == data_dims.size() * 2 auto data_shape = vectorize(data_dims); if (static_cast(paddings->size()) == data_dims.size()) { for (int i = 0; i < data_dims.size(); ++i) { T copy_pad = *(paddings->begin() + 2 * i); paddings->insert(paddings->begin() + 2 * i + 1, copy_pad); } } else { PADDLE_ENFORCE_EQ( data_dims.size() * 2, paddings->size(), phi::errors::InvalidArgument( "Attribute padding's size should be the same or twice as the " "input's dimension. " "But recieved: padding's size is %d, padding is [%s]; input's " "dimension is %d, input's shape is [%s].", paddings->size(), make_ddim(*paddings), data_dims.size(), data_dims)); } // when padding_algorithm is "VALID" or "SAME" if (padding_algorithm == "SAME") { for (int i = 0; i < data_dims.size(); ++i) { T out_size = (data_dims[i] + strides[i] - 1) / strides[i]; T pad_sum = std::max((out_size - 1) * strides[i] + ksize[i] - data_shape[i], static_cast(0)); T pad_0 = pad_sum / 2; T pad_1 = pad_sum - pad_0; *(paddings->begin() + i * 2) = pad_0; *(paddings->begin() + i * 2 + 1) = pad_1; // dilation *(dilation->begin() + i) = 1; } } else if (padding_algorithm == "VALID") { for (auto it = paddings->begin(); it != paddings->end(); it++) { *it = 0; } } } inline bool IsExpand(const std::vector& filter_dim, const std::vector& strides, const std::vector& paddings, const std::vector& dilations) { bool filter_1 = true, strides_1 = true, padding_0 = true, dilation_1 = true; for (size_t j = 0; j < strides.size(); ++j) { filter_1 = filter_1 && (static_cast(filter_dim[j + 2]) == 1); strides_1 = strides_1 && (strides[j] == 1); padding_0 = padding_0 && (paddings[j] == 0); dilation_1 = dilation_1 && (dilations[j] == 1); } if (paddings.size() != strides.size()) { for (size_t j = 0; j < paddings.size(); ++j) { padding_0 = padding_0 && (paddings[j] == 0); } } return !(filter_1 && strides_1 && padding_0 && dilation_1); } } // namespace phi