未验证 提交 6f41e177 编写于 作者: Y YangQun 提交者: GitHub

[Zero-Dim] support 0-D tensor for...

[Zero-Dim] support 0-D tensor for reduce/reshape/stack/prelu/expand_v2/gaussion onednn kernels (#52185)

* support 0-D tensor for reduce/reshape/stack/prelu/expand_v2/gaussion ops

* fix gaussian random mkldnn op ut
上级 b33f95b0
...@@ -285,7 +285,8 @@ class ReshapeGradMKLDNNKernel : public ReshapeMKLDNNKernel<T, op_name> { ...@@ -285,7 +285,8 @@ class ReshapeGradMKLDNNKernel : public ReshapeMKLDNNKernel<T, op_name> {
framework::DDim dx_dims; framework::DDim dx_dims;
InferOutputShapeInGrad(ctx, 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<int64_t>{1};
auto dout_type = phi::funcs::ToOneDNNDataType(dout->dtype()); auto dout_type = phi::funcs::ToOneDNNDataType(dout->dtype());
phi::funcs::ReorderOneDNNHandler reorder_handler( phi::funcs::ReorderOneDNNHandler reorder_handler(
...@@ -305,7 +306,9 @@ class ReshapeGradMKLDNNKernel : public ReshapeMKLDNNKernel<T, op_name> { ...@@ -305,7 +306,9 @@ class ReshapeGradMKLDNNKernel : public ReshapeMKLDNNKernel<T, op_name> {
astream.wait(); astream.wait();
dx->Resize(dx_dims); 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<int64_t>{1};
reorder_dst_memory_p->get_desc().reshape(reshape_dims);
} }
void InferOutputShapeInGrad(const framework::ExecutionContext& ctx, void InferOutputShapeInGrad(const framework::ExecutionContext& ctx,
......
...@@ -1083,7 +1083,9 @@ class BroadcastDataOneDNNHandler ...@@ -1083,7 +1083,9 @@ class BroadcastDataOneDNNHandler
: vectorize(out->dims()); : vectorize(out->dims());
const auto src0_md = dnnl::memory::desc( const auto src0_md = dnnl::memory::desc(
src0_tz, OneDNNGetDataType<T>(), GetPlainOneDNNFormat(src0_tz.size())); src0_tz, OneDNNGetDataType<T>(), 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<int64_t>{1};
const auto src1_md = x->mem_desc().reshape(reshape_dims);
dnnl::primitive_attr attributes; dnnl::primitive_attr attributes;
attributes.set_scales(DNNL_ARG_SRC_0, 0, {scale_x}); attributes.set_scales(DNNL_ARG_SRC_0, 0, {scale_x});
...@@ -1127,6 +1129,9 @@ class PReluOneDNNHandler ...@@ -1127,6 +1129,9 @@ class PReluOneDNNHandler
} }
weights_dims = std::move(new_weights_dims); weights_dims = std::move(new_weights_dims);
} }
if (weights_dims.empty()) {
weights_dims = std::vector<int64_t>{1};
}
auto weights_md = memory::desc( auto weights_md = memory::desc(
weights_dims, OneDNNGetDataType<T>(), memory::format_tag::any); weights_dims, OneDNNGetDataType<T>(), memory::format_tag::any);
......
...@@ -39,6 +39,9 @@ void ExpandGradKernel(const Context& dev_ctx, ...@@ -39,6 +39,9 @@ void ExpandGradKernel(const Context& dev_ctx,
if (out_grad_vec_dims == in_grad_vec_dims) { if (out_grad_vec_dims == in_grad_vec_dims) {
dnnl::memory::data_type out_grad_type = dnnl::memory::data_type out_grad_type =
funcs::ToOneDNNDataType(out_grad.dtype()); funcs::ToOneDNNDataType(out_grad.dtype());
if (out_grad_vec_dims.empty()) {
out_grad_vec_dims = std::vector<int64_t>{1};
}
funcs::ReorderOneDNNHandler reorder_handler( funcs::ReorderOneDNNHandler reorder_handler(
out_grad_vec_dims, out_grad.dtype(), out_grad_type, onednn_engine); out_grad_vec_dims, out_grad.dtype(), out_grad_type, onednn_engine);
...@@ -78,8 +81,10 @@ void ExpandGradKernel(const Context& dev_ctx, ...@@ -78,8 +81,10 @@ void ExpandGradKernel(const Context& dev_ctx,
reduction_p->execute(astream, reduction_args); reduction_p->execute(astream, reduction_args);
astream.wait(); astream.wait();
in_grad->set_layout(DataLayout::ONEDNN); in_grad->set_layout(DataLayout::ONEDNN);
in_grad->set_mem_desc( const auto in_grad_md_dims = in_grad->dims().size() != 0
dst_memory_p->get_desc().reshape(vectorize<int64_t>(in_grad->dims()))); ? vectorize<int64_t>(in_grad->dims())
: std::vector<int64_t>{1};
in_grad->set_mem_desc(dst_memory_p->get_desc().reshape(in_grad_md_dims));
} }
} }
} // namespace phi } // namespace phi
......
...@@ -42,10 +42,8 @@ void GaussianKernel(const Context& ctx, ...@@ -42,10 +42,8 @@ void GaussianKernel(const Context& ctx,
} }
out->Resize(phi::make_ddim(shape.GetData())); out->Resize(phi::make_ddim(shape.GetData()));
dnnl::memory::desc out_mem_desc( dnnl::memory::desc out_mem_desc =
vectorize(out->dims()), phi::funcs::make_memory_desc(*out, DataLayout::NCHW);
funcs::ToOneDNNDataType(out->dtype()),
funcs::GetPlainOneDNNFormat(out->dims().size()));
out->set_mem_desc(out_mem_desc); out->set_mem_desc(out_mem_desc);
} }
......
...@@ -77,8 +77,10 @@ void ReduceKernel(const Context& dev_ctx, ...@@ -77,8 +77,10 @@ void ReduceKernel(const Context& dev_ctx,
reorder_p->execute(astream, *reorder_src_memory_p, *reorder_dst_memory_p); reorder_p->execute(astream, *reorder_src_memory_p, *reorder_dst_memory_p);
astream.wait(); astream.wait();
out->set_mem_desc(reorder_dst_memory_p->get_desc().reshape( const auto reshape_dims = out->dims().size() != 0
vectorize<int64_t>(out->dims()))); ? vectorize<int64_t>(out->dims())
: std::vector<int64_t>{1};
out->set_mem_desc(reorder_dst_memory_p->get_desc().reshape(reshape_dims));
} else { } else {
funcs::ReductionOneDNNHandler<T> handler(reduction_type, funcs::ReductionOneDNNHandler<T> handler(reduction_type,
0.0f, 0.0f,
......
...@@ -120,7 +120,7 @@ void ExecuteReshape(const Context& dev_ctx, ...@@ -120,7 +120,7 @@ void ExecuteReshape(const Context& dev_ctx,
const DDim& x_dims, const DDim& x_dims,
DenseTensor* out) { DenseTensor* out) {
auto out_dims = ValidateShape(shape.GetData(), x_dims); 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( funcs::ReorderOneDNNHandler reorder_handler(
x_vec_dims, x_vec_dims,
...@@ -143,8 +143,9 @@ void ExecuteReshape(const Context& dev_ctx, ...@@ -143,8 +143,9 @@ void ExecuteReshape(const Context& dev_ctx,
astream.wait(); astream.wait();
out->Resize(out_dims); out->Resize(out_dims);
out->set_mem_desc( const auto reshape_dims =
reorder_dst_memory_p->get_desc().reshape(vectorize(out_dims))); out_dims.size() != 0 ? vectorize(out_dims) : std::vector<int64_t>{1};
out->set_mem_desc(reorder_dst_memory_p->get_desc().reshape(reshape_dims));
} }
template <typename T, typename Context> template <typename T, typename Context>
......
...@@ -65,6 +65,20 @@ class TestExpandV2ExpandDimOneDNNOp(TestExpandV2OneDNNOp): ...@@ -65,6 +65,20 @@ class TestExpandV2ExpandDimOneDNNOp(TestExpandV2OneDNNOp):
self.expand_times = [2, 1] 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): class TestExpandV2CopyScenarioOneDNNOp(TestExpandV2OneDNNOp):
def init_data(self): def init_data(self):
self.ori_shape = (2, 10, 5) self.ori_shape = (2, 10, 5)
......
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
import unittest import unittest
import numpy as np
import paddle
from paddle.fluid.tests.unittests.eager_op_test import OpTest
from paddle.fluid.tests.unittests.test_gaussian_random_op import ( from paddle.fluid.tests.unittests.test_gaussian_random_op import (
TestGaussianRandomOp, TestGaussianRandomOp,
) )
...@@ -37,5 +41,36 @@ class TestMKLDNNGaussianRandomOpSeed0(TestGaussianRandomOp): ...@@ -37,5 +41,36 @@ class TestMKLDNNGaussianRandomOpSeed0(TestGaussianRandomOp):
} }
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__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -92,6 +92,22 @@ class TestPReluModeElementOneDNNOp(TestPReluModeChannelOneDNNOp): ...@@ -92,6 +92,22 @@ class TestPReluModeElementOneDNNOp(TestPReluModeChannelOneDNNOp):
self.alpha = np.random.random((1, 4, 5, 5)).astype("float32") 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): class TestPReluModeChannel3DOneDNNOp(TestPReluModeChannelOneDNNOp):
def init_attrs(self): def init_attrs(self):
self.mode = "channel" self.mode = "channel"
......
...@@ -78,6 +78,17 @@ class TestReduceSum5DKeepDimsOneDNNOp(TestReduceDefaultWithGradOneDNNOp): ...@@ -78,6 +78,17 @@ class TestReduceSum5DKeepDimsOneDNNOp(TestReduceDefaultWithGradOneDNNOp):
} }
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( class TestReduceSum5DReduceAllKeepDimsOneDNNOp(
TestReduceDefaultWithGradOneDNNOp TestReduceDefaultWithGradOneDNNOp
): ):
...@@ -100,7 +111,10 @@ class TestReduceSum4DReduceAllOneDNNOp(TestReduceDefaultWithGradOneDNNOp): ...@@ -100,7 +111,10 @@ class TestReduceSum4DReduceAllOneDNNOp(TestReduceDefaultWithGradOneDNNOp):
self.outputs = {'Out': self.inputs['X'].sum()} 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( class TestReduceSum4DNoReduceSimpleCopyOneDNNOp(
TestReduceDefaultWithGradOneDNNOp TestReduceDefaultWithGradOneDNNOp
): ):
...@@ -129,6 +143,21 @@ class TestReduceMax3DOneDNNOp(TestReduceSumDefaultOneDNNOp): ...@@ -129,6 +143,21 @@ class TestReduceMax3DOneDNNOp(TestReduceSumDefaultOneDNNOp):
} }
@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( @skip_check_grad_ci(
reason="reduce_max is discontinuous non-derivable function," reason="reduce_max is discontinuous non-derivable function,"
" its gradient check is not supported by unittest framework." " its gradient check is not supported by unittest framework."
...@@ -165,6 +194,21 @@ class TestReduceMin3DOneDNNOp(TestReduceSumDefaultOneDNNOp): ...@@ -165,6 +194,21 @@ class TestReduceMin3DOneDNNOp(TestReduceSumDefaultOneDNNOp):
} }
@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): class TestReduceMean3DOneDNNOp(TestReduceDefaultWithGradOneDNNOp):
def setUp(self): def setUp(self):
self.op_type = "reduce_mean" self.op_type = "reduce_mean"
...@@ -176,6 +220,18 @@ class TestReduceMean3DOneDNNOp(TestReduceDefaultWithGradOneDNNOp): ...@@ -176,6 +220,18 @@ class TestReduceMean3DOneDNNOp(TestReduceDefaultWithGradOneDNNOp):
} }
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): class TestReduceMean4DReduceAllOneDNNOp(TestReduceDefaultWithGradOneDNNOp):
def setUp(self): def setUp(self):
self.op_type = "reduce_mean" self.op_type = "reduce_mean"
......
...@@ -65,6 +65,20 @@ class TestReshape2OneDNNOp(OpTest): ...@@ -65,6 +65,20 @@ class TestReshape2OneDNNOp(OpTest):
self.check_grad(["X"], "Out", check_dygraph=False) 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): class TestReshape2OneDNNOpDimInfer1(TestReshape2OneDNNOp):
def init_data(self): def init_data(self):
self.ori_shape = (5, 25) self.ori_shape = (5, 25)
......
...@@ -72,6 +72,12 @@ class TestStack1DOneDNNOp(TestStack2DOneDNNOp): ...@@ -72,6 +72,12 @@ class TestStack1DOneDNNOp(TestStack2DOneDNNOp):
self.axis = 0 self.axis = 0
class TestStack0DOneDNNOp(TestStack2DOneDNNOp):
def initParameters(self):
self.input_dim = ()
self.axis = 0
class TestStack1DAxis1OneDNNOp(TestStack2DOneDNNOp): class TestStack1DAxis1OneDNNOp(TestStack2DOneDNNOp):
def initParameters(self): def initParameters(self):
self.input_dim = 100 self.input_dim = 100
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册