未验证 提交 9fb7dff3 编写于 作者: A Aurelius84 提交者: GitHub

[Eager]Fix segment_pool/allclose/isclose/scale API bug (#41506) (#41554)

* [Eager]Fix segment_pool/allclose/isclose/scale API bug (#41506)

* [Eager]Fix segment_pool/allclose/isclose/scale API bug

* fix kernel register problem

* add norm, segment_pool (#41465)
Co-authored-by: Nhong <43953930+phlrain@users.noreply.github.com>
上级 f275bf6d
...@@ -19,15 +19,15 @@ namespace ops = paddle::operators; ...@@ -19,15 +19,15 @@ namespace ops = paddle::operators;
namespace plat = paddle::platform; namespace plat = paddle::platform;
using CUDA = paddle::platform::CUDADeviceContext; using CUDA = paddle::platform::CUDADeviceContext;
#define REGISTER_CAST_CUDA_BASE(op_name, ...) \
REGISTER_OP_CUDA_KERNEL( \
op_name, ops::CastOpKernel<CUDA, float>, \
ops::CastOpKernel<CUDA, double>, ops::CastOpKernel<CUDA, int>, \
ops::CastOpKernel<CUDA, int64_t>, ops::CastOpKernel<CUDA, int16_t>, \
ops::CastOpKernel<CUDA, bool>, ops::CastOpKernel<CUDA, uint8_t>, \
ops::CastOpKernel<CUDA, plat::float16>, \
ops::CastOpKernel<CUDA, plat::complex<float>>, \
ops::CastOpKernel<CUDA, plat::complex<double>>, ##__VA_ARGS__);
// See [ why register transfer_dtype_op alias with cast_op? ] in cast_op.cc // See [ why register transfer_dtype_op alias with cast_op? ] in cast_op.cc
REGISTER_CAST_CUDA_BASE(transfer_dtype, ops::CastOpKernel<CUDA, plat::bfloat16>) REGISTER_OP_CUDA_KERNEL(transfer_dtype, ops::CastOpKernel<CUDA, float>,
ops::CastOpKernel<CUDA, double>,
ops::CastOpKernel<CUDA, int>,
ops::CastOpKernel<CUDA, int64_t>,
ops::CastOpKernel<CUDA, int16_t>,
ops::CastOpKernel<CUDA, bool>,
ops::CastOpKernel<CUDA, uint8_t>,
ops::CastOpKernel<CUDA, plat::float16>,
ops::CastOpKernel<CUDA, plat::complex<float>>,
ops::CastOpKernel<CUDA, plat::complex<double>>,
ops::CastOpKernel<CUDA, plat::bfloat16>);
...@@ -126,6 +126,7 @@ class TestBincountOp(OpTest): ...@@ -126,6 +126,7 @@ class TestBincountOp(OpTest):
# without weights # without weights
def setUp(self): def setUp(self):
self.op_type = "bincount" self.op_type = "bincount"
self.python_api = paddle.bincount
self.init_test_case() self.init_test_case()
self.inputs = {"X": self.np_input} self.inputs = {"X": self.np_input}
self.attrs = {"minlength": self.minlength} self.attrs = {"minlength": self.minlength}
...@@ -137,13 +138,14 @@ class TestBincountOp(OpTest): ...@@ -137,13 +138,14 @@ class TestBincountOp(OpTest):
self.Out = np.bincount(self.np_input, minlength=self.minlength) self.Out = np.bincount(self.np_input, minlength=self.minlength)
def test_check_output(self): def test_check_output(self):
self.check_output() self.check_output(check_eager=False)
class TestCase1(TestBincountOp): class TestCase1(TestBincountOp):
# with weights(FLOAT32) # with weights(FLOAT32)
def setUp(self): def setUp(self):
self.op_type = "bincount" self.op_type = "bincount"
self.python_api = paddle.bincount
self.init_test_case() self.init_test_case()
self.inputs = {"X": self.np_input, "Weights": self.np_weights} self.inputs = {"X": self.np_input, "Weights": self.np_weights}
self.attrs = {"minlength": self.minlength} self.attrs = {"minlength": self.minlength}
...@@ -163,6 +165,7 @@ class TestCase2(TestBincountOp): ...@@ -163,6 +165,7 @@ class TestCase2(TestBincountOp):
# with weights(other) # with weights(other)
def setUp(self): def setUp(self):
self.op_type = "bincount" self.op_type = "bincount"
self.python_api = paddle.bincount
self.init_test_case() self.init_test_case()
self.inputs = {"X": self.np_input, "Weights": self.np_weights} self.inputs = {"X": self.np_input, "Weights": self.np_weights}
self.attrs = {"minlength": self.minlength} self.attrs = {"minlength": self.minlength}
......
...@@ -32,6 +32,7 @@ def l2_norm(x, axis, epsilon): ...@@ -32,6 +32,7 @@ def l2_norm(x, axis, epsilon):
class TestNormOp(OpTest): class TestNormOp(OpTest):
def setUp(self): def setUp(self):
self.op_type = "norm" self.op_type = "norm"
self.python_api = paddle.fluid.layers.l2_normalize
self.init_test_case() self.init_test_case()
self.init_dtype() self.init_dtype()
x = np.random.random(self.shape).astype(self.dtype) x = np.random.random(self.shape).astype(self.dtype)
......
...@@ -73,6 +73,17 @@ def compute_segment_min_max(x, segment_ids, pooltype="MAX"): ...@@ -73,6 +73,17 @@ def compute_segment_min_max(x, segment_ids, pooltype="MAX"):
return results, gradient / results.size return results, gradient / results.size
def segment_pool_split(X, SegmentIds, pooltype):
if pooltype == "SUM":
return paddle.incubate.tensor.segment_sum(X, SegmentIds)
elif pooltype == "MEAN":
return paddle.incubate.tensor.segment_mean(X, SegmentIds)
elif pooltype == "MIN":
return paddle.incubate.tensor.segment_min(X, SegmentIds)
elif pooltype == "MAX":
return paddle.incubate.tensor.segment_max(X, SegmentIds)
class TestSegmentOps(OpTest): class TestSegmentOps(OpTest):
def set_data(self): def set_data(self):
x = np.random.uniform(-1, 1, self.shape).astype(self.dtype) x = np.random.uniform(-1, 1, self.shape).astype(self.dtype)
...@@ -90,6 +101,8 @@ class TestSegmentOps(OpTest): ...@@ -90,6 +101,8 @@ class TestSegmentOps(OpTest):
def prepare(self): def prepare(self):
self.op_type = "segment_pool" self.op_type = "segment_pool"
self.python_api = segment_pool_split
self.python_out_sig = ["Out"]
self.dtype = np.float64 self.dtype = np.float64
self.shape = [30, 15] self.shape = [30, 15]
self.attrs = {"pooltype": "SUM"} self.attrs = {"pooltype": "SUM"}
...@@ -105,10 +118,10 @@ class TestSegmentOps(OpTest): ...@@ -105,10 +118,10 @@ class TestSegmentOps(OpTest):
self.outputs = {'Out': result.astype(self.dtype)} self.outputs = {'Out': result.astype(self.dtype)}
def test_check_output(self): def test_check_output(self):
self.check_output() self.check_output(check_eager=True)
def test_check_grad(self): def test_check_grad(self):
self.check_grad(["X"], "Out") self.check_grad(["X"], "Out", check_eager=True)
class TestSegmentSum2(TestSegmentOps): class TestSegmentSum2(TestSegmentOps):
...@@ -259,4 +272,5 @@ class API_SegmentOpsTest(unittest.TestCase): ...@@ -259,4 +272,5 @@ class API_SegmentOpsTest(unittest.TestCase):
if __name__ == '__main__': if __name__ == '__main__':
paddle.enable_static()
unittest.main() unittest.main()
...@@ -52,7 +52,7 @@ def segment_sum(data, segment_ids, name=None): ...@@ -52,7 +52,7 @@ def segment_sum(data, segment_ids, name=None):
""" """
if in_dygraph_mode(): if in_dygraph_mode():
return _C_ops.final_state_segment_pool(data, segment_idsm, "SUM")[0] return _C_ops.final_state_segment_pool(data, segment_ids, "SUM")[0]
if _in_legacy_dygraph(): if _in_legacy_dygraph():
out, tmp = _C_ops.segment_pool(data, segment_ids, 'pooltype', "SUM") out, tmp = _C_ops.segment_pool(data, segment_ids, 'pooltype', "SUM")
return out return out
...@@ -109,7 +109,7 @@ def segment_mean(data, segment_ids, name=None): ...@@ -109,7 +109,7 @@ def segment_mean(data, segment_ids, name=None):
""" """
if in_dygraph_mode(): if in_dygraph_mode():
return _C_ops.final_state_segment_pool(data, segment_idsm, "MEAN")[0] return _C_ops.final_state_segment_pool(data, segment_ids, "MEAN")[0]
if _non_static_mode(): if _non_static_mode():
out, tmp = _C_ops.segment_pool(data, segment_ids, 'pooltype', "MEAN") out, tmp = _C_ops.segment_pool(data, segment_ids, 'pooltype', "MEAN")
return out return out
...@@ -165,7 +165,7 @@ def segment_min(data, segment_ids, name=None): ...@@ -165,7 +165,7 @@ def segment_min(data, segment_ids, name=None):
""" """
if in_dygraph_mode(): if in_dygraph_mode():
return _C_ops.final_state_segment_pool(data, segment_idsm, "MIN")[0] return _C_ops.final_state_segment_pool(data, segment_ids, "MIN")[0]
if _non_static_mode(): if _non_static_mode():
out, tmp = _C_ops.segment_pool(data, segment_ids, 'pooltype', "MIN") out, tmp = _C_ops.segment_pool(data, segment_ids, 'pooltype', "MIN")
...@@ -222,7 +222,7 @@ def segment_max(data, segment_ids, name=None): ...@@ -222,7 +222,7 @@ def segment_max(data, segment_ids, name=None):
""" """
if in_dygraph_mode(): if in_dygraph_mode():
out, tmp = _C_ops.final_state_segment_pool(data, segment_ids, "MAX")[0] out, tmp = _C_ops.final_state_segment_pool(data, segment_ids, "MAX")
return out return out
if _non_static_mode(): if _non_static_mode():
......
...@@ -17,7 +17,7 @@ from ..fluid.layer_helper import LayerHelper ...@@ -17,7 +17,7 @@ from ..fluid.layer_helper import LayerHelper
from ..framework import _varbase_creator, _dygraph_tracer from ..framework import _varbase_creator, _dygraph_tracer
from ..fluid.data_feeder import check_variable_and_dtype, check_type, check_dtype from ..fluid.data_feeder import check_variable_and_dtype, check_type, check_dtype
from ..static import Variable from ..static import Variable
from ..fluid.framework import _in_legacy_dygraph, in_dygraph_mode from ..fluid.framework import _in_legacy_dygraph, in_dygraph_mode, _non_static_mode
from ..fluid.layers import transpose, cast # noqa: F401 from ..fluid.layers import transpose, cast # noqa: F401
from ..fluid import layers from ..fluid import layers
import paddle import paddle
...@@ -1466,10 +1466,7 @@ def bincount(x, weights=None, minlength=0, name=None): ...@@ -1466,10 +1466,7 @@ def bincount(x, weights=None, minlength=0, name=None):
if x.dtype not in [paddle.int32, paddle.int64]: if x.dtype not in [paddle.int32, paddle.int64]:
raise TypeError("Elements in Input(x) should all be integers") raise TypeError("Elements in Input(x) should all be integers")
# if in_dygraph_mode(): if _non_static_mode():
# return _C_ops.final_state_bincount(x, weights, minlength)
if _in_legacy_dygraph():
return _C_ops.bincount(x, weights, "minlength", minlength) return _C_ops.bincount(x, weights, "minlength", minlength)
helper = LayerHelper('bincount', **locals()) helper = LayerHelper('bincount', **locals())
......
...@@ -123,7 +123,12 @@ def allclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None): ...@@ -123,7 +123,12 @@ def allclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None):
""" """
if in_dygraph_mode(): if in_dygraph_mode():
return _C_ops.final_state_allclose(x, y, rtol, atol, equal_nan) # NOTE(dev): Pass tol as Tensor to fix precision loss problem, because
# C++ backend will cast it into float32 if passing float from python.
as_tensor = lambda x: paddle.to_tensor([x], dtype='float64', place='cpu')
return _C_ops.final_state_allclose(x, y,
as_tensor(rtol),
as_tensor(atol), equal_nan)
if _in_legacy_dygraph(): if _in_legacy_dygraph():
return _C_ops.allclose(x, y, 'rtol', return _C_ops.allclose(x, y, 'rtol',
str(rtol), 'atol', str(rtol), 'atol',
...@@ -685,7 +690,12 @@ def isclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None): ...@@ -685,7 +690,12 @@ def isclose(x, y, rtol=1e-05, atol=1e-08, equal_nan=False, name=None):
""" """
if in_dygraph_mode(): if in_dygraph_mode():
return _C_ops.final_state_isclose(x, y, rtol, atol, equal_nan) # NOTE(dev): Pass tol as Tensor to fix precision loss problem, because
# C++ backend will cast it into float32 if passing float from python.
as_tensor = lambda x: paddle.to_tensor([x], dtype='float64', place='cpu')
return _C_ops.final_state_isclose(x, y,
as_tensor(rtol),
as_tensor(atol), equal_nan)
if _in_legacy_dygraph(): if _in_legacy_dygraph():
return _C_ops.isclose(x, y, 'rtol', return _C_ops.isclose(x, y, 'rtol',
str(rtol), 'atol', str(rtol), 'atol',
......
...@@ -1252,6 +1252,16 @@ ...@@ -1252,6 +1252,16 @@
optional : weight optional : weight
backward : nll_loss_grad backward : nll_loss_grad
- api : norm
args : (Tensor x, int axis, float epsilon, bool is_test)
output : Tensor(out), Tensor(norm)
infer_meta :
func : NormInferMeta
kernel :
func : norm
intermediate : norm
backward : norm_grad
- api : not_equal - api : not_equal
args : (Tensor x, Tensor y, int axis = -1) args : (Tensor x, Tensor y, int axis = -1)
output : Tensor output : Tensor
...@@ -1548,6 +1558,7 @@ ...@@ -1548,6 +1558,7 @@
func : SegmentPoolInferMeta func : SegmentPoolInferMeta
kernel : kernel :
func : segment_pool func : segment_pool
data_type : x
backward : segment_pool_grad backward : segment_pool_grad
# selu # selu
......
...@@ -908,6 +908,16 @@ ...@@ -908,6 +908,16 @@
data_type : input data_type : input
optional : weight optional : weight
- backward_api : norm_grad
forward : norm (Tensor x, int axis, float epsilon, bool is_test) -> Tensor(out), Tensor(norm)
args : (Tensor x, Tensor norm, Tensor out_grad, int axis, float epsilon, bool is_test)
output : Tensor(x_grad)
infer_meta :
func : UnchangedInferMeta
param : [x]
kernel :
func : norm_grad
- backward_api : p_norm_grad - backward_api : p_norm_grad
forward : p_norm(Tensor x, float porder, int axis, float epsilon, bool keepdim, bool asvector=false) -> Tensor(out) forward : p_norm(Tensor x, float porder, int axis, float epsilon, bool keepdim, bool asvector=false) -> Tensor(out)
args : (Tensor x, Tensor out, Tensor out_grad, float porder, int axis, float epsilon, bool keepdim, bool asvector) args : (Tensor x, Tensor out, Tensor out_grad, float porder, int axis, float epsilon, bool keepdim, bool asvector)
...@@ -1096,7 +1106,7 @@ ...@@ -1096,7 +1106,7 @@
forward : scale (Tensor x, Scalar scale, float bias, bool bias_after_scale) -> Tensor(out) forward : scale (Tensor x, Scalar scale, float bias, bool bias_after_scale) -> Tensor(out)
args : (Tensor out_grad, Scalar scale=1.0, float bias=0.0, bool bias_after_scale=true) args : (Tensor out_grad, Scalar scale=1.0, float bias=0.0, bool bias_after_scale=true)
output : Tensor(x_grad) output : Tensor(x_grad)
invoke : scale(out_grad, scale, bias, bias_after_scale) invoke : scale(out_grad, scale, 0.0, bias_after_scale)
- backward_api : scatter_grad - backward_api : scatter_grad
forward : scatter (Tensor x, Tensor index, Tensor updates, bool overwrite) -> Tensor(out) forward : scatter (Tensor x, Tensor index, Tensor updates, bool overwrite) -> Tensor(out)
...@@ -1129,6 +1139,8 @@ ...@@ -1129,6 +1139,8 @@
param : [x] param : [x]
kernel : kernel :
func : segment_pool_grad func : segment_pool_grad
data_type : x
optional : summed_ids
- backward_api : selu_grad - backward_api : selu_grad
forward : selu (Tensor x, float scale, float alpha) -> Tensor(out) forward : selu (Tensor x, float scale, float alpha) -> Tensor(out)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册