Skip to content

Commit 6bbddb2

Browse files
Aidenwu0209claude
andauthored
[API Compatibility No.114] support torch-style kwarg input for paddle.masked_fill via decorator -part (PaddlePaddle#77801)
* [API Compatibility No.114] support torch-style kwarg input for paddle.masked_fill via decorator -part Add @param_one_alias(["x", "input"]) decorator on masked_fill() to support PyTorch-style paddle.masked_fill(input=x, mask=mask, value=v). Use decorator approach instead of C++ sink (python_api_info.yaml) because masked_fill's C++ op requires Tensor value but the Python API accepts scalar, and C++ sink would bypass the scalar-to-Tensor conversion. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: retrigger CI for PaddlePaddle#77801 (2nd no-code rerun) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c10bd5a commit 6bbddb2

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

python/paddle/tensor/manipulation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7007,6 +7007,7 @@ def moveaxis(
70077007
return out
70087008

70097009

7010+
@param_one_alias(["x", "input"])
70107011
def masked_fill(
70117012
x, mask: Tensor, value: Numeric, name: str | None = None
70127013
) -> Tensor:

test/legacy_test/test_api_compatibility.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,73 @@ def test_static_Compatibility(self):
941941
np.testing.assert_allclose(out, ref_out)
942942

943943

944+
# Test masked_fill compatibility
945+
class TestMaskedFillAPI(unittest.TestCase):
946+
def setUp(self):
947+
np.random.seed(123)
948+
paddle.enable_static()
949+
self.shape = [3, 3]
950+
self.dtype = 'float32'
951+
self.init_data()
952+
953+
def init_data(self):
954+
self.np_x = np.random.randint(1, 10, self.shape).astype(self.dtype)
955+
self.np_mask = np.random.randint(0, 2, self.shape).astype(bool)
956+
957+
def test_dygraph_compatibility(self):
958+
paddle.disable_static()
959+
x = paddle.to_tensor(self.np_x)
960+
mask = paddle.to_tensor(self.np_mask)
961+
paddle_dygraph_out = []
962+
963+
# Position args (args)
964+
out1 = paddle.masked_fill(x, mask, 0.0)
965+
paddle_dygraph_out.append(out1)
966+
967+
# Paddle keyword args (kwargs)
968+
out2 = paddle.masked_fill(x=x, mask=mask, value=0.0)
969+
paddle_dygraph_out.append(out2)
970+
971+
# Torch keyword args (input alias)
972+
out3 = paddle.masked_fill(input=x, mask=mask, value=0.0)
973+
paddle_dygraph_out.append(out3)
974+
975+
# Verify all outputs are equal
976+
for i in range(1, len(paddle_dygraph_out)):
977+
np.testing.assert_allclose(
978+
paddle_dygraph_out[0].numpy(), paddle_dygraph_out[i].numpy()
979+
)
980+
paddle.enable_static()
981+
982+
def test_static_compatibility(self):
983+
paddle.enable_static()
984+
main = paddle.static.Program()
985+
startup = paddle.static.Program()
986+
with paddle.base.program_guard(main, startup):
987+
x = paddle.static.data(name="x", shape=self.shape, dtype=self.dtype)
988+
mask = paddle.static.data(
989+
name="mask", shape=self.shape, dtype='bool'
990+
)
991+
992+
# Position args
993+
out1 = paddle.masked_fill(x, mask, 0.0)
994+
# Paddle keyword args
995+
out2 = paddle.masked_fill(x=x, mask=mask, value=0.0)
996+
# Torch keyword args (input alias)
997+
out3 = paddle.masked_fill(input=x, mask=mask, value=0.0)
998+
999+
exe = paddle.base.Executor(paddle.CPUPlace())
1000+
fetches = exe.run(
1001+
main,
1002+
feed={"x": self.np_x, "mask": self.np_mask},
1003+
fetch_list=[out1, out2, out3],
1004+
)
1005+
1006+
# Verify all outputs are equal
1007+
for i in range(1, len(fetches)):
1008+
np.testing.assert_allclose(fetches[0], fetches[i])
1009+
1010+
9441011
class TestTanAPI(unittest.TestCase):
9451012
def setUp(self):
9461013
np.random.seed(123)

0 commit comments

Comments
 (0)