Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,11 @@ bool Conv2dOpInferSymbolicShape(pir::Operation *op,
const symbol::ShapeOrDataDimExprs &shape_data = [&] {
std::vector<symbol::DimExpr> out_s_or_d({in_s_or_d.shape()[0]});
if (!channel_last) {
out_s_or_d.push_back(filter_s_or_d.shape()[0]);
if (filter_s_or_d.shape()[1] == 0) {
out_s_or_d.push_back(symbol::DimExpr{0});
} else {
out_s_or_d.push_back(filter_s_or_d.shape()[0]);
}
}

for (size_t i = 0; i < in_data_dims.size(); ++i) {
Expand All @@ -427,7 +431,11 @@ bool Conv2dOpInferSymbolicShape(pir::Operation *op,
out_s_or_d.push_back(output_size);
}
if (channel_last) {
out_s_or_d.push_back(filter_s_or_d.shape()[0]);
if (filter_s_or_d.shape()[1] == 0) {
out_s_or_d.push_back(symbol::DimExpr{0});
} else {
out_s_or_d.push_back(filter_s_or_d.shape()[0]);
}
}

return symbol::ShapeOrDataDimExprs{
Expand Down
21 changes: 11 additions & 10 deletions paddle/phi/infermeta/binary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -588,13 +588,6 @@ void ConvInferMeta(const MetaTensor& input,
const bool channel_last = (config.is_run_mkldnn_kernel == false) &&
(data_format == "NHWC" || data_format == "NDHWC");

for (int i = 0; i < 2; ++i) {
PADDLE_ENFORCE_NE(in_dims[i],
0,
common::errors::InvalidArgument(
"The size of Op(Conv) inputs should not be 0."));
}

PADDLE_ENFORCE_EQ(
in_dims.size() == 4 || in_dims.size() == 5,
true,
Expand Down Expand Up @@ -706,11 +699,15 @@ void ConvInferMeta(const MetaTensor& input,

std::vector<int64_t> output_shape({in_dims[0]});
if (!channel_last) {
output_shape.push_back(filter_dims[0]);
if (filter_dims[1] == 0) {
output_shape.push_back(0);
} else {
output_shape.push_back(filter_dims[0]);
}
}
for (int i = 0; i < in_data_dims.size(); ++i) {
if ((!config.is_runtime) &&
(in_data_dims[i] <= 0 || filter_dims[i + 2] <= 0)) {
(in_data_dims[i] < 0 || filter_dims[i + 2] < 0)) {
output_shape.push_back(-1);
} else {
const int dkernel =
Expand All @@ -723,7 +720,11 @@ void ConvInferMeta(const MetaTensor& input,
}
}
if (channel_last) {
output_shape.push_back(filter_dims[0]);
if (filter_dims[1] == 0) {
output_shape.push_back(0);
} else {
output_shape.push_back(filter_dims[0]);
}
}

out->set_dims(common::make_ddim(output_shape));
Expand Down
13 changes: 13 additions & 0 deletions paddle/phi/kernels/gpu/depthwise_conv_grad_kernel.cu
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "paddle/phi/common/float16.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/kernels/cpu/conv_util.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/funcs/batch_norm_utils.h"
#include "paddle/phi/kernels/funcs/math_function.h"
#include "paddle/phi/kernels/gpu/depthwise_conv.h"
Expand All @@ -40,6 +41,18 @@ void DepthwiseConvGradKernel(const Context& dev_ctx,
const DenseTensor* output_grad = &out_grad;

if (!input_grad && !filter_grad) return;
// 0-size
if (input.numel() == 0) {
if (input_grad) dev_ctx.template Alloc<T>(input_grad);
if (filter_grad) {
phi::Full<T, Context>(
dev_ctx,
phi::IntArray(common::vectorize(filter_grad->dims())),
0,
filter_grad);
}
return;
}

bool has_fuse_relu = dev_ctx.HasDnnAttr("fuse_relu_before_depthwise_conv");
bool fuse_relu =
Expand Down
6 changes: 6 additions & 0 deletions paddle/phi/kernels/gpu/depthwise_conv_kernel.cu
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "paddle/phi/common/float16.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/kernels/cpu/conv_util.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/funcs/batch_norm_utils.h"
#include "paddle/phi/kernels/gpu/depthwise_conv.h"

Expand All @@ -33,6 +34,11 @@ void DepthwiseConvKernel(const Context& dev_ctx,
const std::vector<int>& dilations_t,
const std::string& data_format,
DenseTensor* out) {
if (input.numel() == 0) {
phi::Full<T, Context>(
dev_ctx, phi::IntArray(common::vectorize(out->dims())), 0, out);
return;
}
DenseTensor* output = out;
dev_ctx.template Alloc<T>(output);

Expand Down
14 changes: 13 additions & 1 deletion paddle/phi/kernels/gpudnn/conv_grad_kernel.cu
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
#include "paddle/phi/common/bfloat16.h"
#include "paddle/phi/common/float16.h"
#include "paddle/phi/kernels/cpu/conv_util.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/funcs/batch_norm_utils.h"
#include "paddle/phi/kernels/funcs/padding.h"
#include "paddle/phi/kernels/impl/conv_cudnn_impl.h"

#ifdef PADDLE_WITH_CUDNN_FRONTEND
// clang-format off
#include "paddle/phi/backends/dynload/cudnn_frontend.h"
Expand Down Expand Up @@ -416,6 +416,18 @@ void ConvCudnnGradKernel(const Context& dev_ctx,
const std::string& data_format,
DenseTensor* input_grad,
DenseTensor* filter_grad) {
// 0-size
if (input.numel() == 0) {
if (input_grad) dev_ctx.template Alloc<T>(input_grad);
if (filter_grad) {
phi::Full<T, Context>(
dev_ctx,
phi::IntArray(common::vectorize(filter_grad->dims())),
0,
filter_grad);
}
return;
}
if (input_grad) {
dev_ctx.template Alloc<T>(input_grad);
}
Expand Down
9 changes: 7 additions & 2 deletions paddle/phi/kernels/gpudnn/conv_kernel.cu
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
// limitations under the License.

#include "paddle/phi/kernels/conv_kernel.h"
#include "paddle/phi/kernels/gpudnn/conv_gpudnn.h"

#include "glog/logging.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/gpudnn/conv_gpudnn.h"

#include "paddle/phi/backends/context_pool.h"
#include "paddle/phi/backends/gpu/gpu_context.h"
Expand Down Expand Up @@ -313,6 +313,11 @@ void ConvCudnnKernel(const Context& dev_ctx,
int groups,
const std::string& data_format,
DenseTensor* output) {
if (input.numel() == 0) {
phi::Full<T, Context>(
dev_ctx, phi::IntArray(common::vectorize(output->dims())), 0, output);
return;
}
dev_ctx.template Alloc<T>(output);
std::vector<int> paddings = paddings_t;
std::vector<int> dilations = dilations_t;
Expand Down
15 changes: 14 additions & 1 deletion paddle/phi/kernels/impl/conv_grad_kernel_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
#pragma once

#include "paddle/phi/kernels/cpu/conv_util.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/funcs/batch_norm_utils.h"
#include "paddle/phi/kernels/funcs/blas/blas.h"
#include "paddle/phi/kernels/funcs/im2col.h"
#include "paddle/phi/kernels/funcs/math_function.h"
#include "paddle/phi/kernels/funcs/vol2col.h"

namespace phi {

template <typename T, typename Context>
Expand All @@ -45,6 +45,19 @@ void ConvGradKernel(const Context& dev_ctx,
std::vector<int> dilations = dilations_t;

DenseTensor filter = filter_t;
// 0-size
if (input.numel() == 0) {
if (input_grad) dev_ctx.template Alloc<T>(input_grad);
if (filter_grad) {
phi::Full<T, Context>(
dev_ctx,
phi::IntArray(common::vectorize(filter_grad->dims())),
0,
filter_grad);
}
return;
}

const bool channel_last = (data_format == "NHWC" || data_format == "NDHWC");

DenseTensor transformed_input(input.type());
Expand Down
6 changes: 6 additions & 0 deletions paddle/phi/kernels/impl/conv_kernel_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "paddle/phi/kernels/conv_kernel.h"
#include "paddle/phi/kernels/cpu/conv_util.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/funcs/batch_norm_utils.h"
#include "paddle/phi/kernels/funcs/blas/blas.h"
#include "paddle/phi/kernels/funcs/im2col.h"
Expand All @@ -38,6 +39,11 @@ void ConvKernelImpl(const Context& dev_ctx,
std::vector<int> paddings = paddings_t;
std::vector<int> dilations = dilations_t;
DenseTensor filter = filter_t;
if (input.numel() == 0) {
phi::Full<T, Context>(
dev_ctx, phi::IntArray(common::vectorize(output->dims())), 0, output);
return;
}
// The filter will be reshaped in the calculations,
// so here use an assignment operation,
// that avoids modifying the variable in the Scope.
Expand Down
13 changes: 13 additions & 0 deletions paddle/phi/kernels/xpu/conv_grad_kernel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "paddle/phi/backends/xpu/enforce_xpu.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/kernels/cpu/conv_util.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/xpu/conv_utils_xpu.h"
#include "paddle/phi/kernels/xpu/xpu_api_wrapper.h"
#ifdef PADDLE_WITH_XPU_XRE5
Expand Down Expand Up @@ -47,6 +48,18 @@ void ConvGradKernel(const Context& dev_ctx,
// so here use an assignment operation,
// that avoids modifying the variable in the Scope.
if (!input_grad && !filter_grad) return;
// 0-size
if (input.numel() == 0) {
if (input_grad) dev_ctx.template Alloc<T>(input_grad);
if (filter_grad) {
phi::Full<T, Context>(
dev_ctx,
phi::IntArray(common::vectorize(filter_grad->dims())),
0,
filter_grad);
}
return;
}
PADDLE_ENFORCE_EQ(
data_format == "NDHWC",
false,
Expand Down
6 changes: 6 additions & 0 deletions paddle/phi/kernels/xpu/conv_kernel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "paddle/phi/backends/xpu/enforce_xpu.h"
#include "paddle/phi/core/kernel_registry.h"
#include "paddle/phi/kernels/cpu/conv_util.h"
#include "paddle/phi/kernels/full_kernel.h"
#include "paddle/phi/kernels/xpu/conv_utils_xpu.h"
#include "paddle/phi/kernels/xpu/xpu_api_wrapper.h"
#ifdef PADDLE_WITH_XPU_XRE5
Expand All @@ -37,6 +38,11 @@ void ConvKernel(const Context& dev_ctx,
int groups,
const std::string& data_format,
DenseTensor* out) {
if (input.numel() == 0) {
phi::Full<T, Context>(
dev_ctx, phi::IntArray(common::vectorize(out->dims())), 0, out);
return;
}
using XPUType = typename XPUTypeTrait<T>::Type;
std::vector<int64_t> paddings(paddings_t.begin(), paddings_t.end());
std::vector<int64_t> dilations(dilations_t.begin(), dilations_t.end());
Expand Down
69 changes: 57 additions & 12 deletions test/legacy_test/test_functional_conv1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import unittest
from unittest import TestCase

Expand All @@ -20,6 +21,7 @@
import paddle
import paddle.base.dygraph as dg
import paddle.nn.functional as F
from paddle import base


class TestFunctionalConv1DError(TestCase):
Expand Down Expand Up @@ -70,18 +72,6 @@ def setUp(self):
self.data_format = "NCL"


class TestFunctionalConv1DErrorCase2(TestFunctionalConv1DError):
def setUp(self):
self.input = np.random.randn(0, 0, 0)
self.filter = np.random.randn(1, 0, 0)
self.bias = None
self.padding = 0
self.stride = 1
self.dilation = 1
self.groups = 1
self.data_format = "NCL"


class TestFunctionalConv1D_CPU_FP16(TestCase):
def setUp(self):
self.padding = 0
Expand All @@ -108,5 +98,60 @@ def test_cpu_fp16(self):
np.testing.assert_allclose(y.numpy(), [[[2]]])


class TestFunctionalConv1D_ZeroSize(TestCase):
def init_data(self):
self.input = np.random.randn(0, 1, 2)
self.filter = np.random.randn(1, 1, 2)
self.np_out = np.zeros([0, 1, 1])

def setUp(self):
self.init_data()
self.bias = None
self.padding = 0
self.stride = 1
self.dilation = 1
self.groups = 1
self.data_format = "NCL"
self.places = []
if (
os.environ.get('FLAGS_CI_both_cpu_and_gpu', 'False').lower()
in ['1', 'true', 'on']
or not base.core.is_compiled_with_cuda()
):
self.places.append(base.CPUPlace())
if base.core.is_compiled_with_cuda():
self.places.append(base.CUDAPlace(0))

def test_dygraph(self):
for place in self.places:
with dg.guard(place):
input = paddle.to_tensor(self.input)
input.stop_gradient = False
filter = paddle.to_tensor(self.filter)
filter.stop_gradient = False
y = F.conv1d(
input,
filter,
self.bias,
padding=self.padding,
stride=self.stride,
dilation=self.dilation,
groups=self.groups,
data_format=self.data_format,
)
np.testing.assert_allclose(y.numpy(), self.np_out)
loss = y.sum()
loss.backward()
np.testing.assert_allclose(input.grad.shape, input.shape)
np.testing.assert_allclose(filter.grad, np.zeros(filter.shape))


class TestFunctionalConv1D_ZeroSize2(TestFunctionalConv1D_ZeroSize):
def init_data(self):
self.input = np.random.randn(0, 0, 2)
self.filter = np.random.randn(1, 0, 2)
self.np_out = np.zeros([0, 0, 1])


if __name__ == "__main__":
unittest.main()
Loading