Skip to content
Merged
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
46 changes: 46 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-57741/README.md
Original file line number Diff line number Diff line change
@@ -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.
32 changes: 32 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-57741/environment/README.md
Original file line number Diff line number Diff line change
@@ -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.
43 changes: 43 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-57741/instruction.md
Original file line number Diff line number Diff line change
@@ -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.
73 changes: 73 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-57741/solution/code.patch
Original file line number Diff line number Diff line change
@@ -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<paddle::dialect::MemcpyOp>()) {
+ VLOG(6) << "MemcpyOp need a special handle";
+ int dst_place_type = op->attribute("dst_place_type")
+ .dyn_cast<pir::Int32Attribute>()
+ .data();
+ if (dst_place_type == 1) {
+ res.set_backend(phi::Backend::GPU);
+ }
+ }
+ }
+
if (op->isa<paddle::dialect::LoadCombineOp>()) {
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
65 changes: 65 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.patch
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions swe-paddle/tasks/PaddlePaddle__Paddle-57741/tests/test.sh
Original file line number Diff line number Diff line change
@@ -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