From 9df509f95d380cb8e75ee1384af330e78a13dbee Mon Sep 17 00:00:00 2001 From: nyx-c-language Date: Thu, 23 Jul 2026 07:05:10 +0800 Subject: [PATCH] swe --- .../PaddlePaddle__Paddle-79161/README.md | 44 ++++++ .../environment/README.md | 27 ++++ .../PaddlePaddle__Paddle-79161/instruction.md | 17 ++ .../PaddlePaddle__Paddle-79161/proposal.md | 55 +++++++ .../solution/code.patch | 28 ++++ .../tests/test.patch | 146 ++++++++++++++++++ .../PaddlePaddle__Paddle-79161/tests/test.sh | 4 + 7 files changed, 321 insertions(+) create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-79161/README.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-79161/environment/README.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-79161/instruction.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-79161/proposal.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-79161/solution/code.patch create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.patch create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.sh diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-79161/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/README.md new file mode 100644 index 000000000..c0e7f6594 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/README.md @@ -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. diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-79161/environment/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/environment/README.md new file mode 100644 index 000000000..31864d6e0 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/environment/README.md @@ -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. diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-79161/instruction.md b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/instruction.md new file mode 100644 index 000000000..ddc4d9ff7 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/instruction.md @@ -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。 diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-79161/proposal.md b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/proposal.md new file mode 100644 index 000000000..f138d13ea --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/proposal.md @@ -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 目标,适合作为一个样本。 diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-79161/solution/code.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/solution/code.patch new file mode 100644 index 000000000..3255f040b --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/solution/code.patch @@ -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``). diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.patch new file mode 100644 index 000000000..1af0565d4 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.patch @@ -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 == [] diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.sh b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.sh new file mode 100644 index 000000000..752ed5759 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-79161/tests/test.sh @@ -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