Skip to content
Closed
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
11 changes: 11 additions & 0 deletions paddle/fluid/pybind/arg_pre_process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,17 @@ void AllClosePreProcess(Value* x, Value* y, Value* rtol, Value* atol) {
"allclose", "atol", pir::GetValueDtype(*atol), {phi::DataType::FLOAT64});
}

void NextAfterPreProcess(Value* x, Value* y) {
CheckDataType("nextafter",
"x",
pir::GetValueDtype(*x),
{phi::DataType::FLOAT32, phi::DataType::FLOAT64});
CheckDataType("nextafter",
"y",
pir::GetValueDtype(*y),
{phi::DataType::FLOAT32, phi::DataType::FLOAT64});
}

void GridSamplePreProcess(Tensor* x,
Tensor* grid,
std::string* mode,
Expand Down
2 changes: 2 additions & 0 deletions paddle/fluid/pybind/arg_pre_process.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ void SumPreProcess(Value* x, Value* axis);
void IsClosePreProcess(Value* x, Value* y, Value* rtol, Value* atol);
void AllClosePreProcess(Value* x, Value* y, Value* rtol, Value* atol);

void NextAfterPreProcess(Value* x, Value* y);

void GridSamplePreProcess(Tensor* x,
Tensor* grid,
std::string* mode,
Expand Down
8 changes: 8 additions & 0 deletions paddle/phi/ops/yaml/python_api_info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,11 @@
args_alias:
x : [batch1]
y : [batch2]

- op : nextafter
name : [paddle.nextafter, paddle.Tensor.nextafter]
args_alias :
x: [input]
y: [other]
pre_process:
static_func: NextAfterPreProcess(x, y)
32 changes: 32 additions & 0 deletions python/paddle/_paddle_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,38 @@ def isclose(
""",
)

add_doc_and_signature(
"nextafter",
r"""
Return the next floating-point value after input towards other, elementwise.
The shapes of input and other must be broadcastable.

Args:
x (Tensor): An N-D Tensor, the data type is float32, float64.
y (Tensor): An N-D Tensor, the data type is float32, float64.
name(str, optional):Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

Returns:
out (Tensor): An N-D Tensor, the shape and data type is the same with input.

Examples:
.. code-block:: python

>>> import paddle
>>> out = paddle.nextafter(paddle.to_tensor([1.0,2.0]),paddle.to_tensor([2.0,1.0]))
>>> out
Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
[1.00000012, 1.99999988])
""",
"""
def nextafter(
x : Tensor,
y : Tensor,
name: str | None = None,
*,
out: Tensor | None = None,
) -> Tensor""",
)

# zhengsheng
add_doc_and_signature(
Expand Down
40 changes: 40 additions & 0 deletions python/paddle/compat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,46 @@ def allclose(
).item()


@ForbidKeywordsDecorator(
illegal_keys={"x", "y"},
func_name="paddle.compat.nextafter",
correct_name="paddle.nextafter",
)
def nextafter(
input: Tensor,
other: Tensor,
*,
out: Tensor | None = None,
) -> Tensor:
"""
Return the next floating-point value after input towards other, elementwise.
The shapes of input and other must be broadcastable.

Args:
x (Tensor): An N-D Tensor, the data type is float32, float64.
y (Tensor): An N-D Tensor, the data type is float32, float64.
name(str, optional):Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

Returns:
out (Tensor): An N-D Tensor, the shape and data type is the same with input.

Examples:
.. code-block:: python

>>> import paddle
>>> out = paddle.nextafter(paddle.to_tensor([1.0,2.0]),paddle.to_tensor([2.0,1.0]))
>>> out
Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
[1.00000012, 1.99999988])
"""
_check_out_status(out, False)
result = paddle.nextafter(input, other)
if out is not None:
paddle.assign(result, out)
return out
return result


@ForbidKeywordsDecorator(
illegal_keys={"x", "y"},
func_name="paddle.compat.equal",
Expand Down
37 changes: 1 addition & 36 deletions python/paddle/tensor/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
maximum,
minimum,
multiply,
nextafter,
sign,
sin,
sum,
Expand Down Expand Up @@ -6488,42 +6489,6 @@ def vander(
return res


def nextafter(x: Tensor, y: Tensor, name: str | None = None) -> Tensor:
r"""
Return the next floating-point value after input towards other, elementwise.
The shapes of input and other must be broadcastable.

Args:
x (Tensor): An N-D Tensor, the data type is float32, float64.
y (Tensor): An N-D Tensor, the data type is float32, float64.
name(str, optional):Name for the operation (optional, default is None). For more information, please refer to :ref:`api_guide_Name`.

Returns:
out (Tensor): An N-D Tensor, the shape and data type is the same with input.

Examples:
.. code-block:: python

>>> import paddle
>>> out = paddle.nextafter(paddle.to_tensor([1.0,2.0]),paddle.to_tensor([2.0,1.0]))
>>> out
Tensor(shape=[2], dtype=float32, place=Place(cpu), stop_gradient=True,
[1.00000012, 1.99999988])
"""
if in_dynamic_or_pir_mode():
return _C_ops.nextafter(x, y)
else:
check_variable_and_dtype(x, 'x', ['float32', 'float64'], 'nextafter')
check_variable_and_dtype(y, 'y', ['float32', 'float64'], 'nextafter')
op_type = "nextafter"
helper = LayerHelper(op_type, **locals())
inputs = {"x": x, "y": y}
out = helper.create_variable_for_type_inference(dtype=paddle.float32)
outputs = {"out": out}
helper.append_op(type=op_type, inputs=inputs, outputs=outputs)
return out


def i0(x: Tensor, name: str | None = None) -> Tensor:
r"""
The function used to calculate modified bessel function of order 0.
Expand Down
71 changes: 71 additions & 0 deletions test/legacy_test/test_nextafter_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,5 +171,76 @@ def setUp(self):
self.outputs = {'out': out}


class TestNextafterCompatibility(unittest.TestCase):
def setUp(self):
self.x = np.random.rand(2, 3, 4, 5).astype('float32')
self.y = np.random.rand(2, 3, 4, 5).astype('float32')
self.out = np.nextafter(self.x, self.y)
self.place = get_device_place()

def test_dygraph_Compatibility(self):
paddle.disable_static()
x = paddle.to_tensor(self.x)
y = paddle.to_tensor(self.y)
paddle_dygraph_out = []
# Position args (args)
out1 = paddle.nextafter(x, y)
paddle_dygraph_out.append(out1)
# Key words args (kwargs) for paddle
out2 = paddle.nextafter(x=x, y=y)
paddle_dygraph_out.append(out2)
# Key words args (kwargs) for torch
out3 = paddle.nextafter(input=x, other=y)
paddle_dygraph_out.append(out3)

# Tensor method args
out4 = paddle.empty([])
out5 = x.nextafter(y, out=out4)
paddle_dygraph_out.append(out4)
paddle_dygraph_out.append(out5)
# Tensor method kwargs
out6 = x.nextafter(y, out=out4)
paddle_dygraph_out.append(out6)
# Test out
out7 = paddle.empty([])
paddle.nextafter(x, y, out=out7)
paddle_dygraph_out.append(out7)
# Numpy reference out
ref_out = np.nextafter(self.x, self.y)
# Check
for out in paddle_dygraph_out:
np.testing.assert_allclose(ref_out, out.numpy())
paddle.enable_static()

def test_static_Compatibility(self):
main = paddle.static.Program()
startup = paddle.static.Program()
with paddle.static.program_guard(main, startup):
x = paddle.static.data(
name='x', shape=self.x.shape, dtype='float32'
)
y = paddle.static.data(
name='y', shape=self.y.shape, dtype='float32'
)
# Position args (args)
out1 = paddle.nextafter(x, y)
# Key words args (kwargs) for paddle
out2 = paddle.nextafter(x=x, y=y)
# Key words args (kwargs) for torch
out3 = paddle.nextafter(input=x, other=y)
# Tensor method args
out4 = x.nextafter(y)

exe = paddle.static.Executor(self.place)
fetches = exe.run(
main,
feed={"x": self.x, "y": self.y},
fetch_list=[out1, out2, out3, out4],
)
ref_out = np.nextafter(self.x, self.y)
for out in fetches:
np.testing.assert_allclose(out, ref_out)


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