diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-73535/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/README.md new file mode 100644 index 000000000..6742de5ad --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/README.md @@ -0,0 +1,51 @@ +# PaddlePaddle__Paddle-73535 + +This directory converts Paddle PR #73535 into a SWE-Paddle community task candidate. + +## Source + +| Field | Value | +| --- | --- | +| Repo | `PaddlePaddle/Paddle` | +| PR | [73535](https://github.com/PaddlePaddle/Paddle/pull/73535) | +| PR title | `[Accuracy diff No.112] Fix accuracy diff for paddle.nn.functional.conv1d API` | +| Base commit | `9c1900ce422e3398bfccf95d3d33ba2cfa91faed` | +| Gold commit | `f8e6a83f6cb3725902082e7fbb011d7c1e8f6406` | +| Merged at | `2025-06-24` | +| Task type | `bug_fix` | +| Resource | CPU | +| Scope | Python API (conv1d float16 on CPU) | + +## Summary + +Fix `paddle.nn.functional.conv1d` to correctly handle float16 weight/bias on CPU by converting them to float32 before computation and casting the result back to float16. + +## Why This Is A Good SWE-Paddle Candidate + +- It is derived from a merged Paddle bug-fix PR rather than a synthetic issue. +- The target behavior is isolated to the Python API layer (`conv1d`) and does not require C++ kernel changes. +- The failure is deterministic: the base revision fails when `conv1d` receives float16 weight/bias on CPU because CPU does not support float16 conv operations. +- The task has clear regression coverage for existing float32/float64 conv1d behavior. +- The task runs on CPU and does not require distributed execution, external services, or additional datasets. + +## Files + +- `proposal.md`: candidate proposal for maintainer triage. +- `instruction.md`: self-contained problem statement for the coding agent. +- `solution/code.patch`: gold implementation patch (Python API changes in `conv.py`). +- `tests/test.patch`: tests exposing the target behavior (adds `TestFunctionalConv1D_CPU_FP16`). +- `tests/test.sh`: minimal target test command. +- `environment/README.md`: environment and reproduction notes. + +## Verification + +```bash +bash tests/test.sh +``` + +Expected behavior: + +| Revision state | Existing behavior (P2P) | conv1d F2P | +| --- | ---: | ---: | +| Base + `tests/test.patch` | PASS | FAIL | +| Base + `tests/test.patch` + `solution/code.patch` | PASS | PASS | diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-73535/environment/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/environment/README.md new file mode 100644 index 000000000..6abad6877 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/environment/README.md @@ -0,0 +1,57 @@ +# Environment Notes + +## Expected Environment + +- Repository: `PaddlePaddle/Paddle` +- Base commit: `9c1900ce422e3398bfccf95d3d33ba2cfa91faed` +- Gold commit: `f8e6a83f6cb3725902082e7fbb011d7c1e8f6406` +- Resource: CPU +- GPU required: no +- Patch type: Python API (no C++ kernel changes) +- Python dependencies: PaddlePaddle (source build or pre-built), NumPy + +The verifier should execute against the Paddle source revision represented by the selected patch state. Since the patch only modifies Python code, no recompilation is needed — only the Python files change. + +## Build Instructions + +1. Check out `PaddlePaddle/Paddle` at the base commit. +2. Apply `tests/test.patch`. +3. Build Paddle from source (CPU-only build is sufficient): +```bash +mkdir build && cd build +cmake .. -DWITH_GPU=OFF -DWITH_TESTING=ON -DCMAKE_BUILD_TYPE=Release +make -j$(nproc) +``` +4. Install the built Paddle package. + +## Run Order + +1. Check out `PaddlePaddle/Paddle` at the base commit. +2. Build and install Paddle from source. +3. Apply `tests/test.patch`. +4. Run the P2P tests; existing conv1d behavior should pass. +5. Run the CPU float16 test; the target case should fail before the fix. +6. Apply `solution/code.patch`. +7. Repackage and reinstall the Python files so the modified `conv.py` takes effect: +```bash +cd python +python setup.py bdist_wheel +pip install --force-reinstall dist/paddlepaddle-*.whl +cd .. +``` +8. Run `bash tests/test.sh`; all target tests should pass. + +## Minimal Test Command + +```bash +bash tests/test.sh +``` + +## Expected Matrix + +| Revision state | P2P | conv1d F2P | +| --- | ---: | ---: | +| Base + test patch | PASS | FAIL | +| Base + test patch + solution patch | PASS | PASS | + +No GPU, distributed runtime, external service, or additional dataset is required. diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-73535/instruction.md b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/instruction.md new file mode 100644 index 000000000..619d9ac62 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/instruction.md @@ -0,0 +1,43 @@ +# 修复 `paddle.nn.functional.conv1d` 在 CPU 上对 float16 weight/bias 的支持 + +## 详细描述 + +当 `paddle.nn.functional.conv1d(x, weight, bias, ...)` 在 CPU 设备上运行时,如果 `weight` 或 `bias` 的 dtype 为 `float16`,当前实现会直接调用底层 `conv2d` 算子,但 CPU 的 `conv2d` 算子不支持 `float16` 输入,导致运行时报错或精度异常。 + +典型表现包括: + +- CPU 环境下传入 float16 的 weight/bias 时,conv1d 计算报错或产生错误结果 +- PaddleAPITest 精度对比测试中 `paddle.nn.functional.conv1d` 在 CPU 上出现 accuracy diff + +例如: + +```python +import paddle +import paddle.nn.functional as F + +with paddle.base.device_guard("cpu"): + x = paddle.ones([1, 1, 1]) + w = paddle.ones([1, 1, 1]).astype(paddle.float16) + b = paddle.ones([1]).astype(paddle.float16) + y = F.conv1d(x, w, b) + # 期望: y 的值为 [[[2]]],dtype 为 float16 +``` + +上述调用中 weight 和 bias 均为 float16,在 CPU 上应能正确执行并返回 float16 类型的结果。 + +当前 `conv1d` 函数在将 1D 卷积转换为 2D 卷积之前,没有对 CPU 设备上的 float16 输入进行类型转换处理。需要在调用底层 conv2d 算子之前,检测 CPU 设备并将 float16 的 weight 和 bias 临时转换为 x 的 dtype(通常为 float32),完成计算后再将结果转换回 float16。 + +## 验收说明 + +- 当 CPU 设备上 weight 或 bias 为 float16 时,`paddle.nn.functional.conv1d` 应正常完成计算 +- 输出的 dtype 应保持为 float16(与输入 weight 的 dtype 一致) +- 输出的数值应与 GPU 上 float16 conv1d 的结果一致(精度在可接受范围内) +- 非 float16 输入(float32、float64 等)下的 conv1d 行为不得退化 +- 非 CPU 设备(GPU)上的 conv1d 行为不受影响 + +## 技术要求 + +- 熟悉 Python 和 Paddle 动态图 API 开发 +- 了解 Paddle 设备(device)检测和 dtype 转换机制 +- 了解 conv1d 到 conv2d 的转换实现 +- 不需要修改 C++ kernel,仅需修改 Python 层代码 diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-73535/proposal.md b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/proposal.md new file mode 100644 index 000000000..7d9c82f94 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/proposal.md @@ -0,0 +1,58 @@ +# SWE-Paddle Task Proposal: PaddlePaddle__Paddle-73535 + +## 1. 来源信息 + +- Instance ID: `PaddlePaddle__Paddle-73535` +- PR 链接: https://github.com/PaddlePaddle/Paddle/pull/73535 +- PR 标题: `[Accuracy diff No.112] Fix accuracy diff for paddle.nn.functional.conv1d API` +- Base commit: `9c1900ce422e3398bfccf95d3d33ba2cfa91faed` +- Gold commit: `f8e6a83f6cb3725902082e7fbb011d7c1e8f6406` +- Merged at: 2025-06-24 +- 你的身份: contributor + +## 2. 问题一句话 + +`paddle.nn.functional.conv1d` 在 CPU 上不支持 float16 的 weight/bias,需要在 Python 层将 float16 临时转为 float32 计算后再转回 float16。 + +## 3. 为什么适合作为 SWE-Paddle 样本 + +- **真实性**: 来自 PaddleAPITest 精度对比测试发现的真实问题(PFCCLab/PaddleAPITest#306)。 +- **代表性**: 覆盖 Python API 层的设备/dtype 兼容性修复,涉及设备检测、dtype 转换和结果还原。 +- **边界清楚**: 目标仅限 CPU 设备上 float16 weight/bias 的 conv1d 调用;其他设备和 dtype 不受影响。 +- **非平凡性**: 修复需要理解 conv1d 到 conv2d 的转换流程,在正确的位置插入 dtype 转换逻辑,并确保输出 dtype 正确还原。 +- **回归护栏明确**: 目标 F2P 可覆盖 CPU float16 conv1d 测试;同文件中已有的 `TestFunctionalConv1DError` 等标准测试用例可作为 P2P 护栏。 + +## 4. 任务类型和标签 + +- 任务类型: `bug_fix` +- 执行后端: `cpu` +- 设备范围: `cpu_only` +- 模块标签: `[python_api, conv1d, float16, cpu_compatibility, dtype_conversion]` + +## 5. 验证思路 + +- 目标测试命令: `bash tests/test.sh` +- 目标测试文件: + - `test/legacy_test/test_functional_conv1d.py`(`TestFunctionalConv1D_CPU_FP16`) +- P2P 候选: 同文件中已有的 `TestFunctionalConv1DError`(含 `Case1`、`Case2`)等标准 conv1d 测试用例。 +- 修复前预期: `base_commit` + `tests/test.patch` 后,CPU float16 conv1d 测试失败(CPU conv2d 不支持 float16)。 +- 修复后预期: 继续应用 `solution/code.patch` 后,CPU float16 conv1d 正常返回正确结果,P2P 存量测试仍然通过。 + +## 6. 环境与资源 + +- 是否能提供 Docker: 无 +- Dockerfile 或镜像地址: 暂无 +- Paddle 来源: `PaddlePaddle/Paddle` source checkout at `base_commit`,需要源码编译(或安装对应版本的 Paddle)。 +- OS / Python / CUDA / cuDNN / 其他关键依赖: Linux CPU + Python + numpy;编译需要 CMake、GCC;不要求 CUDA/cuDNN(CPU 编译即可验证)。 +- 硬件: CPU 即可(编译和测试均不需要 GPU)。 +- patch 类型: 仅 Python 代码修改(`python/paddle/nn/functional/conv.py`),无需重新编译。 +- 最小测试命令: `bash tests/test.sh` +- 是否有 oracle 日志: 无 + +## 7. 风险自查 + +- 泄露风险: 正式 `instruction.md` 只描述「conv1d 在 CPU 上对 float16 weight/bias 的行为异常」,不指出具体的转换代码位置或实现细节。 +- 环境风险: 中。任务需要 Paddle 源码环境,但 patch 仅涉及 Python 文件,无需重新编译。 +- flaky 风险: 低。测试使用固定的小 tensor 构造,不依赖随机数差异或多设备同步。 +- 拆分风险: 低。该 PR 目标集中在 `conv1d` 函数的 CPU float16 兼容处理,测试明确指向 `TestFunctionalConv1D_CPU_FP16`,适合作为一个独立样本。 +- 其他不确定点: 完整任务包阶段应确认新增 F2P(`TestFunctionalConv1D_CPU_FP16`)在 `base_commit` 上确实失败。 diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-73535/solution/code.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/solution/code.patch new file mode 100644 index 000000000..903cf1220 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/solution/code.patch @@ -0,0 +1,46 @@ +diff --git a/python/paddle/nn/functional/conv.py b/python/paddle/nn/functional/conv.py +index 5e5cfed220..067de2c6cf 100644 +--- a/python/paddle/nn/functional/conv.py ++++ b/python/paddle/nn/functional/conv.py +@@ -16,6 +16,7 @@ from __future__ import annotations + + from typing import TYPE_CHECKING + ++import paddle + from paddle import _C_ops, _legacy_C_ops, get_flags, in_dynamic_mode, pir + from paddle.base.framework import _global_flags, in_dynamic_or_pir_mode + from paddle.device import ( +@@ -458,6 +459,15 @@ def conv1d( + dilation = [1, *convert_to_list(dilation, 1, "dilation")] + from ...tensor.creation import assign as paddle_assign + ++ # cpu not support float16, need to convert dtype. ++ float16_convert = False ++ if paddle.device.get_device() == "cpu": ++ if weight.dtype == paddle.float16: ++ float16_convert = True ++ weight = weight.astype(x.dtype) ++ if bias is not None and bias.dtype == paddle.float16: ++ float16_convert = True ++ bias = bias.astype(x.dtype) + weight = paddle_assign(weight) + weight = unsqueeze(weight, axis=[-2]) + +@@ -475,7 +485,6 @@ def conv1d( + + squeeze_axis = -3 if channel_last else -2 + x = unsqueeze(x, axis=[squeeze_axis]) +- + if in_dynamic_or_pir_mode(): + if l_type == 'conv2d': + out = _C_ops.conv2d( +@@ -530,6 +539,9 @@ def conv1d( + if bias is not None: + out = _add_with_axis(out, bias, axis=channel_dim) + out = squeeze(out, axis=[squeeze_axis]) ++ if float16_convert: ++ # out is float16 ++ out = out.astype(paddle.float16) + return out + + diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-73535/tests/test.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/tests/test.patch new file mode 100644 index 000000000..2636b11f8 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/tests/test.patch @@ -0,0 +1,36 @@ +diff --git a/test/legacy_test/test_functional_conv1d.py b/test/legacy_test/test_functional_conv1d.py +index 751b35b255..760e1a2f2b 100644 +--- a/test/legacy_test/test_functional_conv1d.py ++++ b/test/legacy_test/test_functional_conv1d.py +@@ -82,5 +82,31 @@ class TestFunctionalConv1DErrorCase2(TestFunctionalConv1DError): + self.data_format = "NCL" + + ++class TestFunctionalConv1D_CPU_FP16(TestCase): ++ def setUp(self): ++ self.padding = 0 ++ self.stride = 1 ++ self.dilation = 1 ++ self.groups = 1 ++ self.data_format = "NCL" ++ ++ def test_cpu_fp16(self): ++ with dg.guard(paddle.CPUPlace()): ++ x = paddle.ones([1, 1, 1]) ++ w = paddle.ones([1, 1, 1]).astype(paddle.float16) ++ b = paddle.ones([1]).astype(paddle.float16) ++ y = F.conv1d( ++ x, ++ w, ++ b, ++ padding=self.padding, ++ stride=self.stride, ++ dilation=self.dilation, ++ groups=self.groups, ++ data_format=self.data_format, ++ ) ++ np.testing.assert_allclose(y.numpy(), [[[2]]]) ++ ++ + if __name__ == "__main__": + unittest.main() diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-73535/tests/test.sh b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/tests/test.sh new file mode 100644 index 000000000..45bc1deb8 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-73535/tests/test.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +# P2P tests (pass-to-pass) +python -m pytest test/legacy_test/test_functional_conv1d.py::TestFunctionalConv1DError -q + +# F2P tests (fail-to-pass) +python -m pytest test/legacy_test/test_functional_conv1d.py::TestFunctionalConv1D_CPU_FP16 -q