From 8dfc60fb49f32a31794303dff1583ae0f0168f13 Mon Sep 17 00:00:00 2001 From: yangguohao <1901212980@pku.edu.cn> Date: Fri, 7 Aug 2026 00:03:28 -0500 Subject: [PATCH] [SWE-Paddle] Complete task package for PaddlePaddle__Paddle-57741 Co-authored-by: Cursor --- .../PaddlePaddle__Paddle-57741/README.md | 46 ++++++++++++ .../environment/README.md | 32 ++++++++ .../PaddlePaddle__Paddle-57741/instruction.md | 43 +++++++++++ .../solution/code.patch | 73 +++++++++++++++++++ .../tests/test.patch | 65 +++++++++++++++++ .../PaddlePaddle__Paddle-57741/tests/test.sh | 11 +++ 6 files changed, 270 insertions(+) create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-57741/README.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-57741/environment/README.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-57741/instruction.md create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-57741/solution/code.patch create mode 100644 swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.patch create mode 100755 swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.sh diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-57741/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/README.md new file mode 100644 index 000000000..7c0dbd9b6 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/README.md @@ -0,0 +1,46 @@ +# PaddlePaddle__Paddle-57741 + +This directory converts Paddle PR #57741 into a SWE-Paddle community task candidate (PIR: add `memcpy`). + +## Source + +| Field | Value | +| --- | --- | +| Repo | `PaddlePaddle/Paddle` | +| Primary PR | [57741](https://github.com/PaddlePaddle/Paddle/pull/57741) | +| PR title | `【PIR】add memcpy in PIR` | +| Base commit | `f984ed1a56960aeee0059c67b965406984565356` | +| Gold endpoint | `4288e25e07895e2fd9985b7a2ec94baedac39159` | +| Merged at | `2023-10-23` | +| Proposal | community `#1487` | +| Task type | `feature_enhancement` | +| Resource | CPU (source build required) | + +## Summary + +在 PIR 路径下补齐 `memcpy` 算子支持,使动转静场景中的 Tensor 设备间拷贝用例可在 PIR 下正确运行。 + +## Why This Sample + +- **真实 PIR 迁移**:来自已合入的框架算子迁 PIR PR。 +- **基础算子路径**:覆盖 YAML / compat、kernel pass 与动转静测试开启。 +- **边界清晰**:目标集中在 `memcpy`;不扩展到其他设备管理 API。 +- **需 source build**:含 C++ / YAML / pass,不能只靠 wheel overlay。 + +## Files + +- `proposal.md`: approved proposal (do not modify in this package PR). +- `instruction.md`: self-contained problem statement for the coding agent. +- `solution/code.patch`: gold production patch relative to base. +- `tests/test.patch`: test patch exposing the target behavior. +- `tests/test.sh`: minimal target test command. +- `environment/README.md`: base commit and reproduction notes. + +## Verification + +```bash +bash tests/test.sh +``` + +Expected: with `tests/test.patch` on `base_commit`, PIR memcpy related cases fail/error. +After `solution/code.patch` and rebuild, target cases pass. diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-57741/environment/README.md b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/environment/README.md new file mode 100644 index 000000000..62c06685b --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/environment/README.md @@ -0,0 +1,32 @@ +# Environment Notes + +SWE-Paddle task candidate for PaddlePaddle/Paddle PR #57741. + +## Expected Environment + +- Repository: `PaddlePaddle/Paddle` +- Base commit: `f984ed1a56960aeee0059c67b965406984565356` (parent of #57741 merge `4288e25e`) +- Gold endpoint: `4288e25e07895e2fd9985b7a2ec94baedac39159` +- Resource: CPU +- GPU required: no (CPU memcpy cases are the primary gate; GPU cases optional if CUDA is available) +- Patch type: **source build required**. Production changes include PIR op YAML, compat, and `pd_op_to_kernel_pass` C++. +- Paddle install: source checkout at `base_commit`, build/install so PIR dy2static paths are available. + +## Run Order (Run / Test / Fix) + +1. Check out `PaddlePaddle/Paddle` at the base commit and complete a source build/install. +2. Apply `tests/test.patch`. +3. Run `bash tests/test.sh`; PIR memcpy related cases should **fail / error** before the fix. +4. Apply `solution/code.patch` and **rebuild** (YAML / C++ / pass changes). +5. Run `bash tests/test.sh` again; all target cases should **pass**. + +## Minimal Test Command + +```bash +bash tests/test.sh +``` + +## Known Risks + +- Historical PIR stack requires era-matched source build; newer trees may not apply patches cleanly. +- GPU memcpy cases need a CUDA build; CPU-only environments should rely on the CPU test file. diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-57741/instruction.md b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/instruction.md new file mode 100644 index 000000000..c7c73ba9c --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/instruction.md @@ -0,0 +1,43 @@ +# 在 PIR 路径下补齐 memcpy 算子支持 + +## 详细描述 + +在动转静(`to_static`)场景中,Tensor 在不同 Place 之间拷贝(例如 CPU ↔ CUDA)依赖框架内部的 `memcpy` 能力。当前在 PIR 执行路径下,该能力缺失或不完整,导致相关拷贝用例无法在 PIR 下正确运行。 + +需要达成的目标: + +- 在 PIR 路径下支持 `memcpy`,使动转静场景中的 Tensor 设备间拷贝可以完成。 +- 至少覆盖默认在 CPU 上的拷贝相关用例;若环境具备 CUDA,相关 GPU 用例也应可走通。 +- 拷贝后的 place 与数值结果应与非 PIR / 既有路径一致。 +- 不要求扩展到其他无关的设备管理或拷贝 API。 + +## 问题复现(示意) + +在目标 `base_commit` 对应版本上: + +1. 构造简单动转静函数,对 Tensor 执行跨 Place 拷贝(例如拷到 CPU / CUDA)。 +2. 在 PIR 对比 / 开启路径下运行上述用例。 +3. 可观察到算子缺失、lowering 失败,或拷贝结果 / place 不符合预期。 + +## 期望行为 + +- PIR 下 `memcpy` 相关路径可运行。 +- 拷贝后的 place 与数值与既有非 PIR 行为一致(在任务覆盖范围内)。 +- 既有无关动转静行为不被破坏。 + +## 验收说明 + +- 上述目标行为可用,相关用例通过。 +- 已有无关动转静语义不被破坏。 +- 不允许通过删除测试、弱化断言或大范围绕过校验来「通过」任务。 + +## 技术要求 + +- 熟悉 Python 与 C++ +- 了解 Paddle PIR 算子声明、兼容配置与 kernel lowering 相关机制 + +## Acceptance Criteria + +- The behavior described above should be implemented. +- Existing valid behavior should remain unchanged. +- Do not satisfy the task by deleting tests, weakening assertions, or bypassing validation broadly. diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-57741/solution/code.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/solution/code.patch new file mode 100644 index 000000000..d9c181832 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/solution/code.patch @@ -0,0 +1,73 @@ +diff --git a/paddle/fluid/pir/dialect/op_generator/ops_api_gen.py b/paddle/fluid/pir/dialect/op_generator/ops_api_gen.py +--- a/paddle/fluid/pir/dialect/op_generator/ops_api_gen.py ++++ b/paddle/fluid/pir/dialect/op_generator/ops_api_gen.py +@@ -101,6 +101,7 @@ + 'fused_bn_add_activation_', + 'fused_feedforward', + 'fused_scale_bias_relu_conv_bnstats', ++ 'memcpy', + 'print', + 'recv_v2', + 'rnn_', +diff --git a/paddle/fluid/pir/dialect/operator/ir/ops.yaml b/paddle/fluid/pir/dialect/operator/ir/ops.yaml +--- a/paddle/fluid/pir/dialect/operator/ir/ops.yaml ++++ b/paddle/fluid/pir/dialect/operator/ir/ops.yaml +@@ -81,6 +81,16 @@ + args : (Tensor[] x) + output : Tensor(out) + ++- op : memcpy ++ args : (Tensor x, int dst_place_type) ++ output : Tensor(out) ++ infer_meta: ++ func: UnchangedInferMeta ++ param: [x] ++ kernel: ++ func : memcpy ++ param: [x, dst_place_type] ++ + - op : print + args : (Tensor in, int first_n, str message, int summarize, bool print_tensor_name = true, bool print_tensor_type = true, bool print_tensor_shape = true, bool print_tensor_layout = true, bool print_tensor_lod = true, str print_phase = "BOTH", bool is_forward = true) + output : Tensor(out) +diff --git a/paddle/fluid/pir/transforms/pd_op_to_kernel_pass.cc b/paddle/fluid/pir/transforms/pd_op_to_kernel_pass.cc +--- a/paddle/fluid/pir/transforms/pd_op_to_kernel_pass.cc ++++ b/paddle/fluid/pir/transforms/pd_op_to_kernel_pass.cc +@@ -678,6 +678,22 @@ + + phi::KernelKey res(kernel_backend, kernel_layout, kernel_data_type); + ++ // kernel backend infered incorrectly from memcpy op operands, ++ // case that place from (not GPU) to GPU. ++ // We handle this special case by following code to fix up the problem. ++ // This could be further improved if we had another method. ++ if (!platform::is_gpu_place(place)) { ++ if (op->isa()) { ++ VLOG(6) << "MemcpyOp need a special handle"; ++ int dst_place_type = op->attribute("dst_place_type") ++ .dyn_cast() ++ .data(); ++ if (dst_place_type == 1) { ++ res.set_backend(phi::Backend::GPU); ++ } ++ } ++ } ++ + if (op->isa()) { + res.set_dtype(phi::DataType::FLOAT32); + VLOG(8) << "LoadCombineOp's kernel data type must be FLOAT32"; +diff --git a/paddle/phi/api/yaml/op_compat.yaml b/paddle/phi/api/yaml/op_compat.yaml +--- a/paddle/phi/api/yaml/op_compat.yaml ++++ b/paddle/phi/api/yaml/op_compat.yaml +@@ -3275,6 +3275,12 @@ + attrs: + pivot : pivots + ++- op: memcpy ++ inputs: ++ x: X ++ outputs: ++ out: Out ++ + - op: memcpy_d2h + inputs : + x : X diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.patch b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.patch new file mode 100644 index 000000000..9865f0f28 --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.patch @@ -0,0 +1,65 @@ +diff --git a/test/dygraph_to_static/test_tensor_memcpy_on_cpu.py b/test/dygraph_to_static/test_tensor_memcpy_on_cpu.py +--- a/test/dygraph_to_static/test_tensor_memcpy_on_cpu.py ++++ b/test/dygraph_to_static/test_tensor_memcpy_on_cpu.py +@@ -15,6 +15,7 @@ + import unittest + + import numpy as np ++from dygraph_to_static_util import test_and_compare_with_new_ir + + import paddle + +@@ -47,6 +48,7 @@ + x2 = tensor_copy_to_cpu(x1) + return x1.place, x2.place, x2.numpy() + ++ @test_and_compare_with_new_ir(False) + def test_tensor_cpu_on_default_cpu(self): + paddle.base.framework._set_expected_place(paddle.CPUPlace()) + dygraph_x1_place, dygraph_place, dygraph_res = self._run( +@@ -67,6 +69,7 @@ + x2 = tensor_copy_to_cuda(x1) + return x1.place, x2.place, x2.numpy() + ++ @test_and_compare_with_new_ir(False) + def test_tensor_cuda_on_default_cpu(self): + if not paddle.base.is_compiled_with_cuda(): + return +diff --git a/test/dygraph_to_static/test_tensor_memcpy_on_gpu.py b/test/dygraph_to_static/test_tensor_memcpy_on_gpu.py +--- a/test/dygraph_to_static/test_tensor_memcpy_on_gpu.py ++++ b/test/dygraph_to_static/test_tensor_memcpy_on_gpu.py +@@ -16,6 +16,7 @@ + import unittest + + import numpy as np ++from dygraph_to_static_util import test_and_compare_with_new_ir + + import paddle + +@@ -48,6 +49,7 @@ + x2 = tensor_copy_to_cpu(x1) + return x1.place, x2.place, x2.numpy() + ++ @test_and_compare_with_new_ir(False) + def test_tensor_cpu_on_default_gpu(self): + if paddle.base.is_compiled_with_cuda(): + place = paddle.CUDAPlace( +@@ -74,6 +76,7 @@ + x2 = tensor_copy_to_cuda(x1) + return x1.place, x2.place, x2.numpy() + ++ @test_and_compare_with_new_ir(False) + def test_tensor_cuda_on_default_gpu(self): + if paddle.base.is_compiled_with_cuda(): + place = paddle.CUDAPlace( +diff --git a/test/white_list/new_ir_op_test_white_list b/test/white_list/new_ir_op_test_white_list +--- a/test/white_list/new_ir_op_test_white_list ++++ b/test/white_list/new_ir_op_test_white_list +@@ -136,6 +136,7 @@ + test_matrix_power_op + test_maxout_op + test_mean_op ++test_memcpy_op + test_mode_op + test_multi_dot_op + test_multiplex_op diff --git a/swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.sh b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.sh new file mode 100755 index 000000000..192cfc4ec --- /dev/null +++ b/swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Target tests for PaddlePaddle__Paddle-57741. +# Run from the root of a built PaddlePaddle/Paddle source checkout. +python -m pytest \ + test/dygraph_to_static/test_tensor_memcpy_on_cpu.py \ + -q + +# Optional if CUDA is available: +# python -m pytest test/dygraph_to_static/test_tensor_memcpy_on_gpu.py -q