Skip to content
Open
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
44 changes: 44 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-79161/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# PaddlePaddle__Paddle-79161

This directory converts Paddle PR #79161 into a SWE-Paddle community task candidate.

## Source

| Field | Value |
| --- | --- |
| Repo | `PaddlePaddle/Paddle` |
| PR | [79161](https://github.com/PaddlePaddle/Paddle/pull/79161) |
| PR title | `[API Compatibility] Add param alias for paddle.set_rng_state` |
| Base commit | `8dd02b271734f7aae3669fe6dbcbea57d9cc9add` |
| Merged at | `2026-05-28` |
| Task type | `feature_enhancement` |
| Resource | CPU |

## Summary

Add a compatible alias `new_state` for the existing `state_list` parameter of `paddle.set_rng_state`, while keeping the original calling method unchanged.

## Why This Is A Good SWE-Paddle Candidate

- It adds a user-visible API compatibility capability rather than repairing an internal-only failure.
- The production change is Python-only and limited to one public random-state API.
- Independent behavior tests can distinguish Base and Solution on CPU without source build, GPU, or external data.
- Positional and original keyword calls provide clear P2P coverage, while alias dispatch and conflict handling provide direct F2P signals.

## Files

- `proposal.md`: candidate proposal for maintainer triage.
- `instruction.md`: self-contained problem statement for the coding agent.
- `solution/code.patch`: gold patch from the merged PR.
- `tests/test.patch`: test patch exposing the target behavior.
- `tests/test.sh`: minimal target test command.
- `environment/README.md`: environment notes for reproduction.
- `README.md`: task overview and verification entrypoint.

## Verification

```bash
bash tests/test.sh
```

Expected behavior: applying `tests/test.patch` to `base_commit` should fail on the target behavior; applying both `tests/test.patch` and `solution/code.patch` should pass the target tests.
27 changes: 27 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-79161/environment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Environment Notes

This candidate is part of the SWE-Paddle community task set.

## Expected Environment

- Repository: `PaddlePaddle/Paddle`
- Base commit: `8dd02b271734f7aae3669fe6dbcbea57d9cc9add`
- Resource: CPU
- GPU required: no
- Build path: Python-only checkout source with an AST overlay for the target random-state function; no Paddle source build is required.

## Run Order

1. Check out `PaddlePaddle/Paddle` at the base commit.
2. Apply `tests/test.patch`.
3. Run `bash tests/test.sh`; the target behavior should fail before the fix.
4. Apply `solution/code.patch`.
5. Run `bash tests/test.sh` again; the target behavior should pass after the gold patch.

## Minimal Test Command

```bash
bash tests/test.sh
```

The verifier is responsible for deriving stable F2P and P2P node IDs from repeated runs.
17 changes: 17 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-79161/instruction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 为 paddle.set_rng_state 增加 new_state 参数别名

## 详细描述

`paddle.set_rng_state` 当前仅接受 `state_list` 作为随机数生成器状态参数。使用其他框架风格代码或自动迁移工具时,调用方可能使用语义等价的 `new_state` 参数,导致现有 API 无法直接兼容。该 API 应支持 `new_state` 作为 `state_list` 的等价别名,同时保持原有调用方式和错误语义稳定。

## 验收说明

- `paddle.set_rng_state(new_state=...)` 应与使用 `state_list=...` 产生相同的状态设置行为。
- positional 参数和原有 `state_list=` 关键字调用应保持兼容。
- 同时传入 `state_list` 与 `new_state` 时,应明确拒绝冲突输入。

## 技术要求

- 熟悉 Python function signature 和 decorator 行为。
- 了解 Paddle random generator state API。
- 能够编写稳定的 API compatibility behavior tests。
55 changes: 55 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-79161/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Task Proposal: PaddlePaddle__Paddle-79161

## 1. 来源信息

- Instance ID:`PaddlePaddle__Paddle-79161`
- PR 链接:https://github.com/PaddlePaddle/Paddle/pull/79161
- PR 标题:`[API Compatibility] Add param alias for paddle.set_rng_state`
- `base_commit`:`8dd02b271734f7aae3669fe6dbcbea57d9cc9add`
- merged 时间:`2026-05-28`
- 你的身份:熟悉该模块的 contributor
- 后续联系人:TBD

## 2. 问题一句话

为 `paddle.set_rng_state` 的 `state_list` 参数增加等价别名 `new_state`,提升与其他框架风格调用的兼容性。

## 3. 为什么适合作为 SWE-Paddle 样本

- **真实性**:该任务来自已合入的 Paddle API Compatibility PR,不是合成任务。
- **代表性**:它覆盖公共 Python API 的参数 alias、向后兼容和冲突参数语义。
- **边界清楚**:production 行为集中在 `paddle.set_rng_state` 的调用签名兼容性。
- **非平凡性**:实现不仅要接受新 alias,还必须保留 positional 与原关键字调用,并正确拒绝同时传入 canonical 参数和 alias 的冲突场景。
- **环境友好性**:目标逻辑为 Python-only,可通过 checkout source AST overlay 在 CPU 环境稳定验证,无需 source build。

## 4. 任务类型和标签

- 任务类型:`feature_enhancement`
- 执行后端:`cpu`
- 设备范围:`cpu_only`
- 模块标签:`[random, api_compatibility, parameter_alias, decorator, python_only]`

## 5. 验证思路

- 目标测试命令:`bash tests/test.sh`
- 目标测试文件:`test/swe_paddle/test_pr79161_set_rng_state_alias.py`
- 修复前预期:positional 和 `state_list=` 既有调用通过;`new_state=` alias 与 alias 冲突语义测试失败。
- 修复后预期:继续应用 `solution/code.patch` 后,全部目标测试通过。
- P2P 候选:positional state list、原 `state_list=` 关键字和显式 CPU device 参数的既有行为。

## 6. 环境与资源

- 资源需求:CPU
- Paddle 来源:`PaddlePaddle/Paddle` source checkout at `base_commit`
- 是否能提供 Docker:暂无
- patch 类型:Python-only
- 环境建议:从 checkout source 提取 `set_rng_state` 的真实 function 与 decorator control flow,并以 controlled CPU place 和 generator doubles 观察 state side effect,无需导入完整历史 Paddle 模块。
- 最小测试命令:`bash tests/test.sh`
- 是否有 oracle 日志:由 SWE-Paddle verifier 结果另行维护

## 7. 风险自查

- 泄露风险:`instruction.md` 仅描述公共 API 行为,不指出具体 decorator 或修改行。
- 环境风险:AST overlay 避免历史 source 与当前 Paddle wheel 的整体 import 兼容问题。
- flaky 风险:测试只验证确定性的参数映射、异常类型和 CPU generator side effect,不依赖随机采样结果。
- 拆分风险:alias 支持及其冲突语义属于同一个公共 API compatibility 目标,适合作为一个样本。
28 changes: 28 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-79161/solution/code.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
diff --git a/python/paddle/framework/random.py b/python/paddle/framework/random.py
index d623182e024674e2da74690307417d757d465268..f00353b5d973ae3449e85420740932a375fb3a0c 100644
--- a/python/paddle/framework/random.py
+++ b/python/paddle/framework/random.py
@@ -18,6 +18,7 @@ from typing import TYPE_CHECKING

import paddle
from paddle.base import core
+from paddle.utils.decorator_utils import param_one_alias

if TYPE_CHECKING:
from collections.abc import Sequence
@@ -150,6 +151,7 @@ def get_cuda_rng_state() -> list[paddle.base.core.GeneratorState]:
return state_list


+@param_one_alias(["state_list", "new_state"])
def set_rng_state(
state_list: Sequence[paddle.base.core.GeneratorState],
device: str | None = None,
@@ -160,6 +162,7 @@ def set_rng_state(

Args:
state_list(list|tuple): The device states to set back to device generators. state_list is obtained from get_rng_state().
+ Alias: ``new_state``.
device(str): This parameter determines the specific running device.
It can be ``cpu``, ``gpu``, ``xpu``, Default is None.
If None, return the generators of current device (specified by ``set_device``).
146 changes: 146 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
diff --git a/test/swe_paddle/test_pr79161_set_rng_state_alias.py b/test/swe_paddle/test_pr79161_set_rng_state_alias.py
new file mode 100644
index 0000000..11ceea9
--- /dev/null
+++ b/test/swe_paddle/test_pr79161_set_rng_state_alias.py
@@ -0,0 +1,140 @@
+import ast
+import copy
+import functools
+from pathlib import Path
+from types import SimpleNamespace
+
+import pytest
+
+
+TARGET = Path("python/paddle/framework/random.py")
+
+
+class _CPUPlace:
+ pass
+
+
+class _CUDAPlace:
+ pass
+
+
+class _XPUPlace:
+ pass
+
+
+class _CustomPlace:
+ pass
+
+
+class _Generator:
+ def __init__(self):
+ self.states = []
+
+ def set_state(self, state):
+ self.states.append(state)
+
+
+def _param_one_alias(names):
+ canonical, alias = names
+
+ def decorator(function):
+ @functools.wraps(function)
+ def wrapper(*args, **kwargs):
+ if alias in kwargs:
+ if canonical in kwargs:
+ raise ValueError(
+ f"Cannot specify both '{canonical}' and its alias '{alias}'."
+ )
+ kwargs[canonical] = kwargs.pop(alias)
+ return function(*args, **kwargs)
+
+ return wrapper
+
+ return decorator
+
+
+class _StripAnnotations(ast.NodeTransformer):
+ def visit_arg(self, node):
+ node.annotation = None
+ return node
+
+ def visit_FunctionDef(self, node):
+ self.generic_visit(node)
+ node.returns = None
+ return node
+
+
+def _load_checkout_function():
+ tree = ast.parse(TARGET.read_text(encoding="utf-8"), filename=str(TARGET))
+ function = next(
+ node
+ for node in tree.body
+ if isinstance(node, ast.FunctionDef) and node.name == "set_rng_state"
+ )
+ function = _StripAnnotations().visit(copy.deepcopy(function))
+ ast.fix_missing_locations(function)
+
+ generator = _Generator()
+ converted_devices = []
+
+ def convert_to_place(device):
+ converted_devices.append(device)
+ return _CPUPlace()
+
+ core = SimpleNamespace(
+ CPUPlace=_CPUPlace,
+ default_cpu_generator=lambda: generator,
+ get_cuda_device_count=lambda: 0,
+ get_xpu_device_count=lambda: 0,
+ get_all_custom_device_type=lambda: [],
+ get_custom_device_count=lambda _device_type: 0,
+ )
+ paddle = SimpleNamespace(
+ CPUPlace=_CPUPlace,
+ CUDAPlace=_CUDAPlace,
+ XPUPlace=_XPUPlace,
+ CustomPlace=_CustomPlace,
+ framework=SimpleNamespace(
+ _current_expected_place_=lambda: _CPUPlace()
+ ),
+ device=SimpleNamespace(_convert_to_place=convert_to_place),
+ )
+ namespace = {
+ "core": core,
+ "paddle": paddle,
+ "param_one_alias": _param_one_alias,
+ }
+ module = ast.Module(body=[function], type_ignores=[])
+ exec(compile(module, str(TARGET), "exec"), namespace)
+ return namespace["set_rng_state"], generator, converted_devices
+
+
+def test_existing_state_list_calls_remain_valid():
+ function, generator, converted_devices = _load_checkout_function()
+ positional_state = object()
+ keyword_state = object()
+
+ function([positional_state])
+ function(state_list=[keyword_state], device="cpu")
+
+ assert generator.states == [positional_state, keyword_state]
+ assert converted_devices == ["cpu"]
+
+
+def test_new_state_alias_sets_the_same_generator_state():
+ function, generator, converted_devices = _load_checkout_function()
+ aliased_state = object()
+
+ function(new_state=[aliased_state], device="cpu")
+
+ assert generator.states == [aliased_state]
+ assert converted_devices == ["cpu"]
+
+
+def test_state_list_and_new_state_conflict_is_rejected():
+ function, generator, _ = _load_checkout_function()
+
+ with pytest.raises(ValueError, match="Cannot specify both"):
+ function(state_list=[object()], new_state=[object()])
+
+ assert generator.states == []
4 changes: 4 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -euo pipefail

python -m pytest test/swe_paddle/test_pr79161_set_rng_state_alias.py -q