From 4d4208a53c1f831286da24bfec8ac00c8a0e987b Mon Sep 17 00:00:00 2001 From: co63oc <4617245+co63oc@users.noreply.github.com> Date: Wed, 29 Jul 2026 17:15:43 +0800 Subject: [PATCH 1/2] [SWE-Paddle] Add task PaddlePaddle__Paddle-74212 --- .../PaddlePaddle__Paddle-74212/README.md | 51 ++++++++++++++++ .../environment/README.md | 51 ++++++++++++++++ .../PaddlePaddle__Paddle-74212/instruction.md | 53 +++++++++++++++++ .../PaddlePaddle__Paddle-74212/proposal.md | 58 +++++++++++++++++++ .../solution/code.patch | 24 ++++++++ .../tests/test.patch | 53 +++++++++++++++++ .../PaddlePaddle__Paddle-74212/tests/test.sh | 4 ++ 7 files changed, 294 insertions(+) create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-74212/README.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-74212/environment/README.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-74212/instruction.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-74212/proposal.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-74212/solution/code.patch create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.patch create mode 100755 swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/README.md new file mode 100644 index 000000000..54798d113 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/README.md @@ -0,0 +1,51 @@ +# PaddlePaddle__Paddle-74212 + +This directory converts Paddle PR #74212 into a SWE-Paddle community task candidate. + +## Source + +| Field | Value | +| --- | --- | +| Repo | `PaddlePaddle/Paddle` | +| PR | [74212](https://github.com/PaddlePaddle/Paddle/pull/74212) | +| PR title | `[0-size Tensor Job2 No.51] Add 0-size Tensor support for paddle.multiplex` | +| Base commit | `0f3860d981460b0b788aa50836a215f59c90e32a` | +| Gold commit | `3e59330aa066d997e24ff6c5c74c19b250fae43d` | +| Merged at | `2025-07-28` | +| Task type | `bug_fix` | +| Resource | CPU | +| Scope | C++ Operator Kernel | + +## Summary + +Fix `paddle.multiplex` to correctly handle 0-size tensors in CPU/GPU kernels by adding early-return logic when output numel is 0. + +## 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 C++ operator kernel level and requires rebuilding Paddle from source. +- The failure is deterministic: the base revision fails when processing 0-size tensors due to PADDLE_ENFORCE_GT checks on input numel. +- The task has clear regression coverage for existing non-zero-size 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 (C++ kernel changes). +- `tests/test.patch`: tests exposing the target behavior. +- `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) | multiplex F2P | +| --- | ---: | ---: | +| Base + `tests/test.patch` | PASS | FAIL | +| Base + `tests/test.patch` + `solution/code.patch` | PASS | PASS | diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/environment/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/environment/README.md new file mode 100644 index 000000000..bb6d7b394 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/environment/README.md @@ -0,0 +1,51 @@ +# Environment Notes + +## Expected Environment + +- Repository: `PaddlePaddle/Paddle` +- Base commit: `0f3860d981460b0b788aa50836a215f59c90e32a` +- Gold commit: `3e59330aa066d997e24ff6c5c74c19b250fae43d` +- Resource: CPU +- GPU required: no +- Patch type: C++ kernel (CPU/GPU backends) +- Python dependencies: PaddlePaddle (source build), NumPy + +The verifier should execute against the Paddle source revision represented by the selected patch state. A source build is required since the patch modifies C++ kernel code. + +## 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 non-zero-size behavior should pass. +5. Run the 0-size tensor tests; the target case should fail before the fix. +6. Apply `solution/code.patch`. +7. Rebuild Paddle from source. +8. Run `bash tests/test.sh`; all target tests should pass. + +## Minimal Test Command + +```bash +bash tests/test.sh +``` + +## Expected Matrix + +| Revision state | P2P | multiplex 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-74212/instruction.md b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/instruction.md new file mode 100644 index 000000000..6f47bf6f5 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/instruction.md @@ -0,0 +1,53 @@ +# 修复 `paddle.multiplex` 对 0-size Tensor 的处理 + +## 详细描述 + +当 `paddle.multiplex(inputs, index)` 的所有输入 `inputs` 均为 0-size Tensor(即 `out.numel() == 0`)时,当前 CPU/GPU kernel 实现会直接进入后续计算逻辑,导致 kernel 内部的 `PADDLE_ENFORCE_GT(ins[i]->numel(), 0, ...)` 检查失败并报错。 + +典型表现包括: + +- kernel 抛出 `PreconditionNotMet` 错误,提示输入 numel 必须大于 0 +- 0-size Tensor 输入无法通过 multiplex 算子 + +例如: + +```python +import numpy as np +import paddle + +paddle.disable_static() +rows = 4 +index = np.array([0, 2, 2, 3]).astype('int32') +index = np.reshape(index, (rows, 1)) +ins1 = np.random.random((rows, 0)).astype('float64') +ins2 = np.random.random((rows, 0)).astype('float64') +ins3 = np.random.random((rows, 0)).astype('float64') +ins4 = np.random.random((rows, 0)).astype('float64') + +x1 = paddle.to_tensor(ins1) +x2 = paddle.to_tensor(ins2) +x3 = paddle.to_tensor(ins3) +x4 = paddle.to_tensor(ins4) +ids = paddle.to_tensor(index) + +out = paddle.multiplex([x1, x2, x3, x4], ids) +``` + +上述调用中所有输入的 shape 为 `[4, 0]`,`out.numel() == 0`。按照 API semantics,当所有输入均为 0-size 时,不存在需要多路选择的数据,因此该调用应正常完成并返回正确 shape 的空 Tensor。 + +当前 C++ kernel 层在进入后续计算之前,没有对 0-size 输出进行显式的早期返回处理。当 `out->numel() == 0` 时,应在完成 output tensor 的 Alloc 之后,直接返回,跳过后续的 numel 检查和数据拷贝逻辑。 + +## 验收说明 + +- 当所有输入均为 0-size Tensor 时,`paddle.multiplex` kernel 应正常完成,返回正确 shape 的空 Tensor +- 输出的 shape 应与输入一致(除第一维由 index 决定外) +- 非 0-size Tensor 输入下的 multiplex 行为不得退化 +- 梯度计算也应正常工作(0-size Tensor 的梯度也为空 Tensor) + +## 技术要求 + +- 熟悉 C++ 和 Paddle PHI kernel 开发 +- 了解 Tensor shape、0-size Tensor 和 kernel 执行路径 +- 了解 multiplex 算子的输入输出语义 +- 了解 Paddle CPU/GPU kernel 的多 backend 实现模式 +- 需要从源码编译 Paddle 以验证修改 diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/proposal.md b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/proposal.md new file mode 100644 index 000000000..ef1b9db09 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/proposal.md @@ -0,0 +1,58 @@ +# SWE-Paddle Task Proposal: PaddlePaddle__Paddle-74212 + +## 1. 来源信息 + +- Instance ID: `PaddlePaddle__Paddle-74212` +- PR 链接: https://github.com/PaddlePaddle/Paddle/pull/74212 +- PR 标题: `[0-size Tensor Job2 No.51] Add 0-size Tensor support for paddle.multiplex` +- Base commit: `0f3860d981460b0b788aa50836a215f59c90e32a` +- Gold commit: `3e59330aa066d997e24ff6c5c74c19b250fae43d` +- Merged at: 2025-07-28 +- 你的身份: contributor + +## 2. 问题一句话 + +`paddle.multiplex` 在输入为 0-size Tensor 时,kernel 会因 PADDLE_ENFORCE_GT 检查每个输入 numel > 0 而报错,需要在 kernel 入口添加 0-size 早期返回逻辑。 + +## 3. 为什么适合作为 SWE-Paddle 样本 + +- **真实性**: 来自 Paddle「0-size Tensor 机制建设」系列任务,是真实研发需求。 +- **代表性**: 覆盖 C++ kernel 层面的 0-size Tensor 边界处理,涉及 CPU/GPU 双端 kernel,需要在 kernel 入口添加 `out->numel() == 0` 的早期返回。 +- **边界清楚**: 目标仅限所有输入均为 0-size 时的 kernel 早期返回;正向非零尺寸输入不应受影响。 +- **非平凡性**: 修复需要在 CPU/GPU 两个 backend 的 kernel 中分别添加 `if (out->numel() == 0) return;`,涉及对 kernel 执行流程的理解和 0-size Tensor 语义的把握。 +- **回归护栏明确**: 目标 F2P 可覆盖 0-size Tensor 输入的 `multiplex` 算子测试;同文件中已有的 `TestMultiplexOp` 等标准测试用例可作为 P2P 护栏。 + +## 4. 任务类型和标签 + +- 任务类型: `bug_fix` +- 执行后端: `cpu` +- 设备范围: `cpu_only` +- 模块标签: `[operator_kernel, multiplex, 0-size_tensor, cpu_kernel, gpu_kernel]` + +## 5. 验证思路 + +- 目标测试命令: `bash tests/test.sh` +- 目标测试文件: + - `test/legacy_test/test_multiplex_op.py`(`TestMultiplexOp_ZeroSize`) +- P2P 候选: 同文件中已有的 `TestMultiplexOp`、`TestMultiplexODygrap` 等标准 multiplex 算子测试用例。 +- 修复前预期: `base_commit` + `tests/test.patch` 后,0-size Tensor 输入的 `multiplex` 算子测试失败(kernel 内部 PADDLE_ENFORCE_GT 报错)。 +- 修复后预期: 继续应用 `solution/code.patch` 并重新编译后,0-size Tensor 输入正常返回空 Tensor,P2P 存量测试仍然通过。 + +## 6. 环境与资源 + +- 是否能提供 Docker: 无 +- Dockerfile 或镜像地址: 暂无 +- Paddle 来源: `PaddlePaddle/Paddle` source checkout at `base_commit`,需要源码编译。 +- OS / Python / CUDA / cuDNN / 其他关键依赖: Linux CPU + Python + numpy;编译需要 CMake、GCC;不要求 CUDA/cuDNN(CPU 编译即可验证)。 +- 硬件: CPU 即可(编译和测试均不需要 GPU)。 +- patch 类型: 含 C++ kernel 修改(CPU/GPU 双端),需要重新编译 Paddle。 +- 最小测试命令: `bash tests/test.sh` +- 是否有 oracle 日志: 无 + +## 7. 风险自查 + +- 泄露风险: 正式 `instruction.md` 只描述「multiplex 对 0-size Tensor 输入的行为异常」,不指出具体 `out->numel() == 0` 分支逻辑或具体代码位置。 +- 环境风险: 中。任务涉及 C++ kernel 修改,需要源码编译 Paddle,编译时间较长。 +- flaky 风险: 低。测试使用固定的 0-size Tensor 构造,不依赖随机数差异或多设备同步。 +- 拆分风险: 低。该 PR 目标集中在 `multiplex_kernel` 的 CPU/GPU 双端 0-size 早期返回,测试明确指向 `TestMultiplexOp_ZeroSize`,适合作为一个独立样本。 +- 其他不确定点: 完整任务包阶段应确认新增 F2P(`TestMultiplexOp_ZeroSize`)在 `base_commit` 编译后确实失败。 diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/solution/code.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/solution/code.patch new file mode 100644 index 000000000..4d011cf43 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/solution/code.patch @@ -0,0 +1,24 @@ +diff --git a/paddle/phi/kernels/cpu/multiplex_kernel.cc b/paddle/phi/kernels/cpu/multiplex_kernel.cc +index 6e38a255a1..f91879dd45 100644 +--- a/paddle/phi/kernels/cpu/multiplex_kernel.cc ++++ b/paddle/phi/kernels/cpu/multiplex_kernel.cc +@@ -26,6 +26,7 @@ void MultiplexKernel(const Context& dev_ctx, + const DenseTensor& ids, + DenseTensor* out) { + dev_ctx.template Alloc(out); ++ if (out->numel() == 0) return; + for (size_t i = 0; i < ins.size(); ++i) { + PADDLE_ENFORCE_GT( + ins[i]->numel(), +diff --git a/paddle/phi/kernels/gpu/multiplex_kernel.cu b/paddle/phi/kernels/gpu/multiplex_kernel.cu +index 33fa3a74c5..b66cc4836b 100644 +--- a/paddle/phi/kernels/gpu/multiplex_kernel.cu ++++ b/paddle/phi/kernels/gpu/multiplex_kernel.cu +@@ -27,6 +27,7 @@ void MultiplexKernel(const Context& dev_ctx, + const DenseTensor& ids, + DenseTensor* out) { + dev_ctx.template Alloc(out); ++ if (out->numel() == 0) return; + for (size_t i = 0; i < ins.size(); ++i) { + PADDLE_ENFORCE_GT( + ins[i]->numel(), diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.patch new file mode 100644 index 000000000..6246e8f44 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.patch @@ -0,0 +1,53 @@ +diff --git a/test/legacy_test/test_multiplex_op.py b/test/legacy_test/test_multiplex_op.py +index 67d3b0bbf7..0c69efeed9 100644 +--- a/test/legacy_test/test_multiplex_op.py ++++ b/test/legacy_test/test_multiplex_op.py +@@ -97,6 +97,7 @@ class TestMultiplexOp_complex128(TestMultiplexOp): + class TestMultiplexOpError(unittest.TestCase): + + def test_errors(self): ++ paddle.enable_static() + with base.program_guard(base.Program(), base.Program()): + x1 = paddle.static.data(name='x1', shape=[None, 2], dtype='int64') + x2 = paddle.static.data(name='x2', shape=[None, 2], dtype='int64') +@@ -198,5 +199,40 @@ class TestMultiplexODygrap_complex128(TestMultiplexODygrap): + self.dtype = np.complex128 + + ++class TestMultiplexOp_ZeroSize(OpTest): ++ def setUp(self): ++ self.op_type = "multiplex" ++ self.init_dtype() ++ self.python_api = paddle.tensor.multiplex ++ rows = 4 ++ index = np.array([0, 2, 2, 3]).astype('int32') ++ np.random.shuffle(index) ++ index = np.reshape(index, (rows, 1)) ++ ins1 = np.random.random((rows, 0)).astype(self.dtype) ++ ins2 = np.random.random((rows, 0)).astype(self.dtype) ++ ins3 = np.random.random((rows, 0)).astype(self.dtype) ++ ins4 = np.random.random((rows, 0)).astype(self.dtype) ++ self.inputs = { ++ 'Ids': index, ++ 'X': [('x1', ins1), ('x2', ins2), ('x3', ins3), ('x4', ins4)], ++ } ++ # multiplex output ++ output = np.zeros_like(ins1) ++ for i in range(0, rows): ++ k = index[i][0] ++ if self.inputs['X'][k][1][i].size != 0: ++ output[i] = self.inputs['X'][k][1][i] ++ self.outputs = {'Out': output} ++ ++ def init_dtype(self): ++ self.dtype = 'float64' ++ ++ def test_check_output(self): ++ self.check_output(check_pir=True) ++ ++ def test_check_grad(self): ++ self.check_grad(['x1', 'x2', 'x3', 'x4'], 'Out', check_pir=True) ++ ++ + if __name__ == '__main__': + unittest.main() diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh new file mode 100755 index 000000000..d5b13175f --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash +set -euo pipefail + +python -m pytest test/legacy_test/test_multiplex_op.py::TestMultiplexOp_ZeroSize -q From 38c452a895539e24c2acecd928faa122f79a11b3 Mon Sep 17 00:00:00 2001 From: co63oc <4617245+co63oc@users.noreply.github.com> Date: Wed, 29 Jul 2026 17:28:20 +0800 Subject: [PATCH 2/2] Add P2P tests for TestMultiplexOp --- swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh index d5b13175f..9fb891241 100755 --- a/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-74212/tests/test.sh @@ -1,4 +1,8 @@ #!/usr/bin/env bash set -euo pipefail +# P2P tests (pass-to-pass) +python -m pytest test/legacy_test/test_multiplex_op.py::TestMultiplexOp -q + +# F2P tests (fail-to-pass) python -m pytest test/legacy_test/test_multiplex_op.py::TestMultiplexOp_ZeroSize -q