diff --git a/paddle/fluid/operators/mkldnn/reshape_mkldnn_op.cc b/paddle/fluid/operators/mkldnn/reshape_mkldnn_op.cc index 6a6c4df4a5da49..79e84e47553373 100644 --- a/paddle/fluid/operators/mkldnn/reshape_mkldnn_op.cc +++ b/paddle/fluid/operators/mkldnn/reshape_mkldnn_op.cc @@ -285,7 +285,8 @@ class ReshapeGradMKLDNNKernel : public ReshapeMKLDNNKernel { framework::DDim dx_dims; InferOutputShapeInGrad(ctx, dx_dims); - auto dout_vec_dims = phi::vectorize(dout->dims()); + auto dout_vec_dims = dout->dims().size() != 0 ? phi::vectorize(dout->dims()) + : std::vector{1}; auto dout_type = phi::funcs::ToOneDNNDataType(dout->dtype()); phi::funcs::ReorderOneDNNHandler reorder_handler( @@ -305,7 +306,9 @@ class ReshapeGradMKLDNNKernel : public ReshapeMKLDNNKernel { astream.wait(); dx->Resize(dx_dims); - reorder_dst_memory_p->get_desc().reshape(phi::vectorize(dx_dims)); + const auto reshape_dims = + dx_dims.size() != 0 ? phi::vectorize(dx_dims) : std::vector{1}; + reorder_dst_memory_p->get_desc().reshape(reshape_dims); } void InferOutputShapeInGrad(const framework::ExecutionContext& ctx, diff --git a/paddle/phi/backends/onednn/onednn_reuse.h b/paddle/phi/backends/onednn/onednn_reuse.h index 8e0eefb8495f21..c7dcdea0e487cc 100644 --- a/paddle/phi/backends/onednn/onednn_reuse.h +++ b/paddle/phi/backends/onednn/onednn_reuse.h @@ -1083,7 +1083,9 @@ class BroadcastDataOneDNNHandler : vectorize(out->dims()); const auto src0_md = dnnl::memory::desc( src0_tz, OneDNNGetDataType(), GetPlainOneDNNFormat(src0_tz.size())); - const auto src1_md = x->mem_desc().reshape(extended_x_dims); + const auto reshape_dims = + extended_x_dims.size() != 0 ? extended_x_dims : std::vector{1}; + const auto src1_md = x->mem_desc().reshape(reshape_dims); dnnl::primitive_attr attributes; attributes.set_scales(DNNL_ARG_SRC_0, 0, {scale_x}); @@ -1127,6 +1129,9 @@ class PReluOneDNNHandler } weights_dims = std::move(new_weights_dims); } + if (weights_dims.empty()) { + weights_dims = std::vector{1}; + } auto weights_md = memory::desc( weights_dims, OneDNNGetDataType(), memory::format_tag::any); diff --git a/paddle/phi/kernels/onednn/expand_grad_kernel.cc b/paddle/phi/kernels/onednn/expand_grad_kernel.cc index 243505f990d823..8650a90f064fc0 100644 --- a/paddle/phi/kernels/onednn/expand_grad_kernel.cc +++ b/paddle/phi/kernels/onednn/expand_grad_kernel.cc @@ -39,6 +39,9 @@ void ExpandGradKernel(const Context& dev_ctx, if (out_grad_vec_dims == in_grad_vec_dims) { dnnl::memory::data_type out_grad_type = funcs::ToOneDNNDataType(out_grad.dtype()); + if (out_grad_vec_dims.empty()) { + out_grad_vec_dims = std::vector{1}; + } funcs::ReorderOneDNNHandler reorder_handler( out_grad_vec_dims, out_grad.dtype(), out_grad_type, onednn_engine); @@ -78,8 +81,10 @@ void ExpandGradKernel(const Context& dev_ctx, reduction_p->execute(astream, reduction_args); astream.wait(); in_grad->set_layout(DataLayout::ONEDNN); - in_grad->set_mem_desc( - dst_memory_p->get_desc().reshape(vectorize(in_grad->dims()))); + const auto in_grad_md_dims = in_grad->dims().size() != 0 + ? vectorize(in_grad->dims()) + : std::vector{1}; + in_grad->set_mem_desc(dst_memory_p->get_desc().reshape(in_grad_md_dims)); } } } // namespace phi diff --git a/paddle/phi/kernels/onednn/gaussian_kernel.cc b/paddle/phi/kernels/onednn/gaussian_kernel.cc index bd293d553930c5..a850aee10c31bb 100644 --- a/paddle/phi/kernels/onednn/gaussian_kernel.cc +++ b/paddle/phi/kernels/onednn/gaussian_kernel.cc @@ -42,10 +42,8 @@ void GaussianKernel(const Context& ctx, } out->Resize(phi::make_ddim(shape.GetData())); - dnnl::memory::desc out_mem_desc( - vectorize(out->dims()), - funcs::ToOneDNNDataType(out->dtype()), - funcs::GetPlainOneDNNFormat(out->dims().size())); + dnnl::memory::desc out_mem_desc = + phi::funcs::make_memory_desc(*out, DataLayout::NCHW); out->set_mem_desc(out_mem_desc); } diff --git a/paddle/phi/kernels/onednn/reduce_kernel_impl.h b/paddle/phi/kernels/onednn/reduce_kernel_impl.h index 7a2f66ec984e58..d9e01f79bed6ad 100644 --- a/paddle/phi/kernels/onednn/reduce_kernel_impl.h +++ b/paddle/phi/kernels/onednn/reduce_kernel_impl.h @@ -77,8 +77,10 @@ void ReduceKernel(const Context& dev_ctx, reorder_p->execute(astream, *reorder_src_memory_p, *reorder_dst_memory_p); astream.wait(); - out->set_mem_desc(reorder_dst_memory_p->get_desc().reshape( - vectorize(out->dims()))); + const auto reshape_dims = out->dims().size() != 0 + ? vectorize(out->dims()) + : std::vector{1}; + out->set_mem_desc(reorder_dst_memory_p->get_desc().reshape(reshape_dims)); } else { funcs::ReductionOneDNNHandler handler(reduction_type, 0.0f, diff --git a/paddle/phi/kernels/onednn/reshape_kernel.cc b/paddle/phi/kernels/onednn/reshape_kernel.cc index 95d27b94a84655..4454b5e9d69158 100644 --- a/paddle/phi/kernels/onednn/reshape_kernel.cc +++ b/paddle/phi/kernels/onednn/reshape_kernel.cc @@ -120,7 +120,7 @@ void ExecuteReshape(const Context& dev_ctx, const DDim& x_dims, DenseTensor* out) { auto out_dims = ValidateShape(shape.GetData(), x_dims); - auto x_vec_dims = vectorize(x_dims); + auto x_vec_dims = x.mem_desc().dims(); funcs::ReorderOneDNNHandler reorder_handler( x_vec_dims, @@ -143,8 +143,9 @@ void ExecuteReshape(const Context& dev_ctx, astream.wait(); out->Resize(out_dims); - out->set_mem_desc( - reorder_dst_memory_p->get_desc().reshape(vectorize(out_dims))); + const auto reshape_dims = + out_dims.size() != 0 ? vectorize(out_dims) : std::vector{1}; + out->set_mem_desc(reorder_dst_memory_p->get_desc().reshape(reshape_dims)); } template diff --git a/test/mkldnn/test_expand_v2_mkldnn_op.py b/test/mkldnn/test_expand_v2_mkldnn_op.py index 225bebaec0c7ec..bcca1649d7891a 100644 --- a/test/mkldnn/test_expand_v2_mkldnn_op.py +++ b/test/mkldnn/test_expand_v2_mkldnn_op.py @@ -65,6 +65,20 @@ def init_data(self): self.expand_times = [2, 1] +class TestExpandV2ExpandDimOneDNNOp_ZeroDim(TestExpandV2OneDNNOp): + def init_data(self): + self.ori_shape = [] + self.shape = [10, 10] + self.expand_times = [10, 10] + + +class TestExpandV2ExpandDimOneDNNOp_ZeroDim2(TestExpandV2OneDNNOp): + def init_data(self): + self.ori_shape = [] + self.shape = [] + self.expand_times = [] + + class TestExpandV2CopyScenarioOneDNNOp(TestExpandV2OneDNNOp): def init_data(self): self.ori_shape = (2, 10, 5) diff --git a/test/mkldnn/test_gaussian_random_mkldnn_op.py b/test/mkldnn/test_gaussian_random_mkldnn_op.py index 8a7c7c23e40f1b..198f2cb91cf2cf 100644 --- a/test/mkldnn/test_gaussian_random_mkldnn_op.py +++ b/test/mkldnn/test_gaussian_random_mkldnn_op.py @@ -14,6 +14,10 @@ import unittest +import numpy as np + +import paddle +from paddle.fluid.tests.unittests.op_test import OpTest from paddle.fluid.tests.unittests.test_gaussian_random_op import ( TestGaussianRandomOp, ) @@ -37,5 +41,36 @@ def setUp(self): } +class TestGaussianRandomOp_ZeroDim(OpTest): + def setUp(self): + self.op_type = "gaussian_random" + self.__class__.op_type = "gaussian_random" + self.python_api = paddle.normal + self.set_attrs() + self.inputs = {} + self.use_mkldnn = True + self.attrs = { + "shape": [], + "mean": self.mean, + "std": self.std, + "seed": 10, + "use_mkldnn": self.use_mkldnn, + } + paddle.seed(10) + + self.outputs = {'Out': np.random.normal(self.mean, self.std, ())} + + def set_attrs(self): + self.mean = 1.0 + self.std = 2.0 + + # TODO(qun) find a way to check a random scalar + def test_check_output(self): + pass + + def test_check_grad(self): + pass + + if __name__ == '__main__': unittest.main() diff --git a/test/mkldnn/test_prelu_mkldnn_op.py b/test/mkldnn/test_prelu_mkldnn_op.py index 39e0cd788e576a..86f31d6e528eac 100644 --- a/test/mkldnn/test_prelu_mkldnn_op.py +++ b/test/mkldnn/test_prelu_mkldnn_op.py @@ -92,6 +92,22 @@ def init_attrs(self): self.alpha = np.random.random((1, 4, 5, 5)).astype("float32") +class TestPReluModeElement0DOneDNNOp(TestPReluModeChannelOneDNNOp): + def init_attrs(self): + self.mode = "all" + self.alpha = np.random.random(()).astype("float32") + + def setUp(self): + self.op_type = "prelu" + self.x = np.random.random(()).astype("float32") + self.init_attrs() + self.set_inputs() + self.attrs = {'mode': self.mode, 'use_mkldnn': True} + self.set_dtype_attr() + + self.outputs = {'Out': self.x if self.x > 0 else self.x * self.alpha} + + class TestPReluModeChannel3DOneDNNOp(TestPReluModeChannelOneDNNOp): def init_attrs(self): self.mode = "channel" diff --git a/test/mkldnn/test_reduce_mkldnn_op.py b/test/mkldnn/test_reduce_mkldnn_op.py index 0d815e0959ff98..4bc3d3a5d97156 100644 --- a/test/mkldnn/test_reduce_mkldnn_op.py +++ b/test/mkldnn/test_reduce_mkldnn_op.py @@ -78,6 +78,17 @@ def setUp(self): } +class TestReduceSum0DOneDNNOp(TestReduceDefaultWithGradOneDNNOp): + def setUp(self): + self.op_type = "reduce_sum" + self.use_mkldnn = True + self.inputs = {'X': np.random.random(()).astype("float32")} + self.attrs = {'use_mkldnn': self.use_mkldnn, 'dim': []} + self.outputs = { + 'Out': self.inputs['X'].sum(axis=tuple(self.attrs['dim'])) + } + + class TestReduceSum5DReduceAllKeepDimsOneDNNOp( TestReduceDefaultWithGradOneDNNOp ): @@ -100,7 +111,10 @@ def setUp(self): self.outputs = {'Out': self.inputs['X'].sum()} -@OpTestTool.skip_if_not_cpu() +@OpTestTool.skip_if( + True, + reason="According to Paddle API, None dim means reduce all instead of copy, so just skip this test to avoid potential failure", +) class TestReduceSum4DNoReduceSimpleCopyOneDNNOp( TestReduceDefaultWithGradOneDNNOp ): @@ -129,6 +143,21 @@ def setUp(self): } +@skip_check_grad_ci( + reason="reduce_max is discontinuous non-derivable function," + " its gradient check is not supported by unittest framework." +) +class TestReduceMax0DOneDNNOp(TestReduceSumDefaultOneDNNOp): + def setUp(self): + self.op_type = "reduce_max" + self.use_mkldnn = True + self.inputs = {'X': np.random.random(()).astype("float32")} + self.attrs = {'use_mkldnn': self.use_mkldnn, 'dim': []} + self.outputs = { + 'Out': self.inputs['X'].max(axis=tuple(self.attrs['dim'])) + } + + @skip_check_grad_ci( reason="reduce_max is discontinuous non-derivable function," " its gradient check is not supported by unittest framework." @@ -165,6 +194,21 @@ def setUp(self): } +@skip_check_grad_ci( + reason="reduce_min is discontinuous non-derivable function," + " its gradient check is not supported by unittest framework." +) +class TestReduceMin0DOneDNNOp(TestReduceSumDefaultOneDNNOp): + def setUp(self): + self.op_type = "reduce_min" + self.use_mkldnn = True + self.inputs = {'X': np.random.random(()).astype("float32")} + self.attrs = {'use_mkldnn': self.use_mkldnn, 'dim': []} + self.outputs = { + 'Out': self.inputs['X'].min(axis=tuple(self.attrs['dim'])) + } + + class TestReduceMean3DOneDNNOp(TestReduceDefaultWithGradOneDNNOp): def setUp(self): self.op_type = "reduce_mean" @@ -176,6 +220,18 @@ def setUp(self): } +class TestReduceMean0DOneDNNOp(TestReduceDefaultWithGradOneDNNOp): + def setUp(self): + self.op_type = "reduce_mean" + self.use_mkldnn = True + self.inputs = {'X': np.random.random(()).astype("float32")} + self.attrs = {'use_mkldnn': self.use_mkldnn, 'dim': []} + self.outputs = { + # scalar mean is equal to sum + 'Out': self.inputs['X'].sum(axis=tuple(self.attrs['dim'])) + } + + class TestReduceMean4DReduceAllOneDNNOp(TestReduceDefaultWithGradOneDNNOp): def setUp(self): self.op_type = "reduce_mean" diff --git a/test/mkldnn/test_reshape_mkldnn_op.py b/test/mkldnn/test_reshape_mkldnn_op.py index 701d4ad28a077a..e07e93cdbc5380 100644 --- a/test/mkldnn/test_reshape_mkldnn_op.py +++ b/test/mkldnn/test_reshape_mkldnn_op.py @@ -65,6 +65,20 @@ def test_check_grad(self): self.check_grad(["X"], "Out", check_dygraph=False) +class TestReshape2OneDNNOpZeroDim(TestReshape2OneDNNOp): + def init_data(self): + self.ori_shape = () + self.new_shape = (1,) + self.infered_shape = (1,) + + +class TestReshape2OneDNNOpZeroDim2(TestReshape2OneDNNOpZeroDim): + def init_data(self): + self.ori_shape = (1,) + self.new_shape = () + self.infered_shape = () + + class TestReshape2OneDNNOpDimInfer1(TestReshape2OneDNNOp): def init_data(self): self.ori_shape = (5, 25) diff --git a/test/mkldnn/test_stack_mkldnn_op.py b/test/mkldnn/test_stack_mkldnn_op.py index 9d2996cd7cbb29..d93c599ab85ecf 100644 --- a/test/mkldnn/test_stack_mkldnn_op.py +++ b/test/mkldnn/test_stack_mkldnn_op.py @@ -72,6 +72,12 @@ def initParameters(self): self.axis = 0 +class TestStack0DOneDNNOp(TestStack2DOneDNNOp): + def initParameters(self): + self.input_dim = () + self.axis = 0 + + class TestStack1DAxis1OneDNNOp(TestStack2DOneDNNOp): def initParameters(self): self.input_dim = 100