Skip to content

Commit 48c74b8

Browse files
authored
[API Compatibility] Add paddle.Tensor.clamp_ ,paddle.nn.functional.logsigmoid, paddle.functional.meshgrid, paddle.nn.init.calculate_fan_in_and_fan_out ,paddle.autocast (#76206)
* sharding stage3 bugfix * sharding stage3 bugfix * sharding stage3 bugfix * sharding stage3 bugfix * sharding stage3 bugfix * sharding stage3 bugfix * support recompute's forward and backward in pipeline mode * [API Compatibility] Add paddle.Tensor.clip_ * Revert "support recompute's forward and backward in pipeline mode" This reverts commit 7fd48d9. * Revert "[API Compatibility] Add paddle.Tensor.clip_" This reverts commit 025efc3. * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast * [API Compatibility] Add clip_、logsigmoid、_calculate_fan_in_and_fan_out、meshgrid、autocast
1 parent 191a334 commit 48c74b8

File tree

10 files changed

+225
-1
lines changed

10 files changed

+225
-1
lines changed

python/paddle/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ def new_init(self, *args, **kwargs):
226226
get_autocast_gpu_dtype,
227227
is_autocast_enabled,
228228
)
229+
from .amp.auto_cast import autocast
229230
from .autograd import (
230231
enable_grad,
231232
grad,
@@ -971,7 +972,6 @@ def __dir__(self):
971972
sub = subtract
972973
sub_ = subtract_
973974

974-
975975
__all__ = [
976976
'block_diag',
977977
'gt',
@@ -1481,6 +1481,7 @@ def __dir__(self):
14811481
'conv3d',
14821482
'manual_seed',
14831483
'softmax',
1484+
'autocast',
14841485
]
14851486
import os
14861487

python/paddle/functional.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
from .compat import split
15+
from .tensor.creation import meshgrid
1516
from .tensor.einsum import einsum
1617
from .tensor.linalg import norm
1718
from .tensor.manipulation import (
@@ -31,4 +32,5 @@
3132
"norm",
3233
'split',
3334
'unique_consecutive',
35+
"meshgrid",
3436
]

python/paddle/nn/functional/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
pixel_unshuffle,
173173
)
174174

175+
logsigmoid = log_sigmoid
175176
__all__ = [
176177
'celu',
177178
'conv1d',
@@ -192,6 +193,7 @@
192193
'leaky_relu',
193194
'leaky_relu_',
194195
'log_sigmoid',
196+
'logsigmoid',
195197
'maxout',
196198
'prelu',
197199
'relu',

python/paddle/nn/functional/activation.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ def relu_(x: Tensor, name: str | None = None) -> Tensor:
754754
return _C_ops.relu_(x)
755755

756756

757+
@param_one_alias(["x", "input"])
757758
def log_sigmoid(x: Tensor, name: str | None = None) -> Tensor:
758759
r"""
759760
log_sigmoid activation.
@@ -764,6 +765,7 @@ def log_sigmoid(x: Tensor, name: str | None = None) -> Tensor:
764765
765766
Parameters:
766767
x (Tensor): The input Tensor with data type float32, float64, complex64, complex128.
768+
Alias: ``input``.
767769
name (str|None, optional): For details, please refer to :ref:`api_guide_Name`. Generally, no setting is required. Default: None.
768770
769771
Returns:

python/paddle/nn/init.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
from __future__ import annotations
1616

17+
import numpy as np
18+
1719
import paddle
1820

1921
from ..base.framework import in_dygraph_mode, in_pir_mode
@@ -27,6 +29,41 @@
2729
from .initializer.xavier import XavierNormal, XavierUniform
2830

2931

32+
def _calculate_fan_in_and_fan_out(var: paddle.Tensor) -> tuple[int, int]:
33+
"""Compute the fan_in and the fan_out for layers
34+
35+
This method computes the fan_in and the fan_out
36+
for neural network layers, if not specified. It is
37+
not possible to perfectly estimate fan_in and fan_out.
38+
This method will estimate it correctly for matrix multiply and
39+
convolutions.
40+
41+
Args:
42+
var: variable for which fan_in and fan_out have to be computed.
43+
44+
Returns:
45+
tuple of two integers (fan_in, fan_out).
46+
"""
47+
shape = var.shape
48+
if not shape or len(shape) == 0:
49+
fan_in = fan_out = 1
50+
elif len(shape) == 1:
51+
fan_in = fan_out = shape[0]
52+
elif len(shape) == 2:
53+
# This is the case for simple matrix multiply
54+
fan_in = shape[0]
55+
fan_out = shape[1]
56+
else:
57+
# Assume this to be a convolutional kernel
58+
# In PaddlePaddle, the shape of the kernel is like:
59+
# [num_filters, num_filter_channels, ...] where the remaining
60+
# dimensions are the filter_size
61+
receptive_field_size = np.prod(shape[2:])
62+
fan_in = int(shape[1] * receptive_field_size)
63+
fan_out = int(shape[0] * receptive_field_size)
64+
return (fan_in, fan_out)
65+
66+
3067
def kaiming_uniform_(
3168
tensor: paddle.Tensor,
3269
a: float = 0,

python/paddle/tensor/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@
515515
greater = gt
516516
sub = subtract
517517
sub_ = subtract_
518+
clamp_ = clip_
518519

519520
# this list used in math_op_patch.py for _binary_creator_
520521
tensor_method_func = [
@@ -947,6 +948,7 @@
947948
'gt',
948949
'greater',
949950
'clamp',
951+
'clamp_',
950952
]
951953

952954

test/legacy_test/test_activation_op.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,53 @@ def test_errors(self):
854854
F.log_sigmoid(x_fp16)
855855

856856

857+
class TestLogSigmoidOutAndParaDecorator(unittest.TestCase):
858+
def setUp(self) -> None:
859+
paddle.disable_static()
860+
self.apis = [
861+
paddle.nn.functional.log_sigmoid,
862+
paddle.nn.functional.logsigmoid,
863+
]
864+
self.shape = [3, 4, 5]
865+
self.input_np = np.random.random(self.shape).astype('float32')
866+
867+
def do_test(self, api, test_type):
868+
self.test_types = [
869+
"decorator1",
870+
]
871+
x = paddle.to_tensor(self.input_np, stop_gradient=False)
872+
out = paddle.zeros(self.shape, dtype='float32')
873+
out.stop_gradient = False
874+
if test_type == "raw":
875+
out = paddle.nn.functional.log_sigmoid(x)
876+
out.mean().backward()
877+
return out, x.grad
878+
elif test_type == "decorator1":
879+
res = api(input=x)
880+
loss = res.mean()
881+
loss.backward()
882+
x_grad = x.grad
883+
return res, x_grad
884+
else:
885+
raise NotImplementedError(
886+
f"Test type {test_type} is not implemented."
887+
)
888+
889+
def test_api(self):
890+
out_std, x_grad_std = self.do_test(
891+
paddle.nn.functional.log_sigmoid, "raw"
892+
)
893+
for api in self.apis:
894+
for test_type in self.test_types:
895+
out, x_grad = self.do_test(api, test_type)
896+
np.testing.assert_allclose(
897+
out.numpy(), out_std.numpy(), rtol=1e-20
898+
)
899+
np.testing.assert_allclose(
900+
x_grad.numpy(), x_grad_std.numpy(), rtol=1e-20
901+
)
902+
903+
857904
class TestTanh(TestActivation, TestParameter):
858905
def setUp(self):
859906
self.op_type = "tanh"

test/legacy_test/test_autocast.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright (c) 2025 PaddlePaddle Authors. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import unittest
16+
17+
import paddle
18+
from paddle.base import core
19+
20+
21+
@unittest.skipIf(
22+
not core.is_compiled_with_cuda() and not core.is_compiled_with_xpu(),
23+
"Require compiled with CUDA or XPU.",
24+
)
25+
@unittest.skipIf(
26+
core.is_compiled_with_cuda()
27+
and paddle.device.cuda.get_device_capability()[0] < 7.0,
28+
"run test when gpu's compute capability is at least 7.0.",
29+
)
30+
@unittest.skipIf(
31+
core.is_compiled_with_xpu()
32+
and core.get_xpu_device_version(0) < core.XPUVersion.XPU3,
33+
"run test when xpu's compute capability >= xpu3.",
34+
)
35+
@unittest.skipIf(
36+
core.is_compiled_with_xpu()
37+
and core.get_xpu_device_version(0) == core.XPUVersion.XPU3,
38+
"Bugs on XPU3, disable temporarily",
39+
)
40+
class TestCudaAutoCast(unittest.TestCase):
41+
def setUp(self):
42+
self._conv = paddle.nn.Conv2D(1, 1, 3, bias_attr=False)
43+
self._linear = paddle.nn.Linear(4, 4)
44+
45+
def _run_autocast_test(self, ctx):
46+
with paddle.autocast(
47+
device_type='cuda',
48+
enabled=True,
49+
dtype=paddle.float16,
50+
cache_enabled=True,
51+
):
52+
out1 = self._conv(paddle.rand(shape=[1, 1, 6, 6], dtype='float32'))
53+
out2 = out1 + paddle.rand(shape=out1.shape, dtype='float16')
54+
out3 = self._linear(out2)
55+
56+
self.assertEqual(out1.dtype, paddle.float16)
57+
self.assertEqual(out2.dtype, paddle.float16)
58+
self.assertEqual(out3.dtype, paddle.float32)
59+
60+
61+
if __name__ == '__main__':
62+
unittest.main()

test/legacy_test/test_clip_op.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,5 +1033,37 @@ def test_static_compatibility(self):
10331033
np.testing.assert_array_equal(self.np_out, fetches[0])
10341034

10351035

1036+
class TestClamp_AndClip_(unittest.TestCase):
1037+
def setUp(self) -> None:
1038+
paddle.disable_static()
1039+
self.shape = [3, 4, 5]
1040+
self.input_np = np.random.random(self.shape).astype('float32')
1041+
self.a = np.random.random(self.shape).astype('float32')
1042+
self.b = np.random.random(self.shape).astype('float32')
1043+
self.min, self.max = -0.5, 0.5
1044+
1045+
def test_clip_and_clamp(self):
1046+
clip_a = paddle.to_tensor(self.a, stop_gradient=False)
1047+
clip_b = paddle.to_tensor(self.b, stop_gradient=False)
1048+
1049+
clamp_a = paddle.to_tensor(self.a, stop_gradient=False)
1050+
clamp_b = paddle.to_tensor(self.b, stop_gradient=False)
1051+
1052+
clip_x = clip_a + clip_b
1053+
clip_x.clip_(min=self.min, max=self.max)
1054+
clip_x.retain_grads()
1055+
clip_x.mean().backward()
1056+
1057+
clamp_x = clamp_a + clamp_b
1058+
clamp_x.clamp_(min=self.min, max=self.max)
1059+
clamp_x.retain_grads()
1060+
clamp_x.mean().backward()
1061+
1062+
np.testing.assert_allclose(clip_x.numpy(), clamp_x.numpy(), rtol=1e-20)
1063+
np.testing.assert_allclose(
1064+
clip_x.grad.numpy(), clamp_x.grad.numpy(), rtol=1e-20
1065+
)
1066+
1067+
10361068
if __name__ == '__main__':
10371069
unittest.main()

test/legacy_test/test_nn_init_function.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ def _calculate_gain(nonlinearity, param):
6262
return recommended_gain[nonlinearity]
6363

6464

65+
def _calculate_fan_in_and_fan_out(var: paddle.Tensor) -> tuple[int, int]:
66+
shape = var.shape
67+
if not shape or len(shape) == 0:
68+
fan_in = fan_out = 1
69+
elif len(shape) == 1:
70+
fan_in = fan_out = shape[0]
71+
elif len(shape) == 2:
72+
fan_in = shape[0]
73+
fan_out = shape[1]
74+
else:
75+
receptive_field_size = np.prod(shape[2:])
76+
fan_in = shape[1] * receptive_field_size
77+
fan_out = shape[0] * receptive_field_size
78+
return (fan_in, fan_out)
79+
80+
6581
class Test_calculate_gain(unittest.TestCase):
6682
def test(self):
6783
for nonlinearity in [
@@ -87,6 +103,27 @@ def test(self):
87103
)
88104

89105

106+
class TestCAlFanINOUT(unittest.TestCase):
107+
def test_cal_fan_in_and_out(self):
108+
x = paddle.tensor.randn([10])
109+
self.assertEqual(
110+
_calculate_fan_in_and_fan_out(x),
111+
paddle.nn.init._calculate_fan_in_and_fan_out(x),
112+
)
113+
114+
y = paddle.tensor.randn([10, 10])
115+
self.assertEqual(
116+
_calculate_fan_in_and_fan_out(y),
117+
paddle.nn.init._calculate_fan_in_and_fan_out(y),
118+
)
119+
120+
z = paddle.randn([10, 10, 10])
121+
self.assertEqual(
122+
_calculate_fan_in_and_fan_out(z),
123+
paddle.nn.init._calculate_fan_in_and_fan_out(z),
124+
)
125+
126+
90127
class Test_kaiming_uniform_(unittest.TestCase):
91128
def check_kaiming_uniform(
92129
self, tensor, a=0, mode='fan_in', nonlinearity='leaky_relu'

0 commit comments

Comments
 (0)