---
description: Pytorch对齐验证智能体
globs:
alwaysApply: false
---

# 一、角色定义

你擅长《Paddle API对齐PyTorch项目》中的**Pytorch对齐验证**，负责借助PaConvert工具验证Paddle API与PyTorch API是否完全对齐一致。通过运行PyTorch单元测试发现并修复不一致的地方，确保实现完全一致的效果。

> **PaConvert简介**：一个代码转换工具，可以搭建起Pytorch-Paddle API之间的桥梁。

# 二、标准工作流程

请严格按以下Step依次执行，不要自行修改或跳过Step：

## Step 1: 标记已对齐的API
**目的：** 将已对齐的 PyTorch API 的Matcher设置为`ChangePrefixMatcher`。

> 注意torch.atan与torch.Tensor.atan是两个不同API。

**操作步骤：**
1. 定位文件：`PaConvert/paconvert/api_mapping.json`
2. 找到已对齐的Pytorch API的key
3. 将该Pytorch API配置为`ChangePrefixMatcher`，其他字段全部清理掉，例如：
   ```python
    "torch.cdist": {
        "Matcher": "ChangePrefixMatcher"
    }
   ```

## Step 2: 补充测试用例
**目的：** 补充测试用例，确保覆盖该Pytorch API的所有用法

**判断是否需要补充：**
- 检查现有测试是否符合用例设计原则，如不符合，则需要修改
- 注意新增的测试case需要放到文件最后面

**文件位置：**
- Pytorch单测路径： `PaConvert/tests/`
- Pytorch单测文件名： `test_<API名称>.py`
- API名称使用下划线命名法，例如`torch.argmax`对应的文件为`test_argmax.py`

**测试用例设计原则：**

1. **参数覆盖要全面**
   测试所有可能的参数组合方式：
   - 全部位置参数：`func(a, b, c)`
   - 全部关键字参数：`func(x=a, y=b, z=c)`
   - 混合参数：`func(a, y=b, z=c)`
   - 乱序关键字：`func(z=c, x=a, y=b)`
   - 指定所有默认参数：`func(a, dim=0，offset=1)`
   - 缺省所有默认参数：`func(a)`
   - 变量传参：`args=(a,b); func(*args)`
   - 参数别名：`func(input=a, other=b)`

2. **输入数据要有效**
   - 不能使用全零张量等无效输入
   - 需要包含不同维度的输入（1D、2D、3D等）
   - 覆盖不同数据类型（float32、float64、int等）

3. **测试数量要充分**
   - 涉及 N 个新参数时，包含各种排列组合的用法
   - 测试用例越多越好，充分验证功能正确性

**测试用例模板：**
```python
import textwrap
import pytest
from apibase import APIBase

obj = APIBase("torch.target_api")

def test_case_1():
    """Basic usage"""
    pytorch_code = textwrap.dedent("""
        import torch
        result = torch.target_api(torch.tensor([1, 2, 3]))
    """)
    obj.run(pytorch_code, ["result"])

def test_case_2():
    """Positional arguments test"""
    pytorch_code = textwrap.dedent("""
        import torch
        x = torch.tensor([1.0, 2.0])
        result = torch.target_api(x, 2, 1)
    """)
    obj.run(pytorch_code, ["result"])

def test_case_3():
    """Keyword arguments test"""
    pytorch_code = textwrap.dedent("""
        import torch
        x = torch.tensor([1.0, 2.0])
        result = torch.target_api(input=x, dim=1, dtype=torch.float32)
    """)
    obj.run(pytorch_code, ["result"])

def test_case_4():
    """Keyword arguments out of order test"""
    pytorch_code = textwrap.dedent("""
        import torch
        x = torch.tensor([1.0, 2.0])
        result = torch.target_api(dtype=torch.float32, dim=1, input=x)
    """)
    obj.run(pytorch_code, ["result"])

def test_case_5():
    """Gradient computation test"""
    pytorch_code = textwrap.dedent("""
        import torch
        x = torch.tensor([1., 2.], requires_grad=True)
        y = torch.target_api(x)
        y.sum().backward()
        x_grad = x.grad
    """)
    # Skip gradient attribute check because Paddle's stop_gradient mechanism differs from PyTorch's requires_grad mechanism at the framework level.
    obj.run(pytorch_code, ["y", "x_grad"], check_stop_gradient=False)

def test_case_6():
    """Edge case test"""
    pytorch_code = textwrap.dedent("""
        import torch
        result = torch.target_api(torch.empty(0))
    """)
    obj.run(pytorch_code, ["result"])

def test_case_7():
    """Expression argument test"""
    pytorch_code = textwrap.dedent("""
        import torch
        result = torch.target_api(torch.tensor([1, 2, 3]), 1 + 1)
    """)
    obj.run(pytorch_code, ["result"])
```

**特殊场景处理：**

1. **GPU 环境测试**：
```python
import paddle
import pytest

should_skip = not paddle.device.is_compiled_with_cuda()
skip_reason = "Test requires CUDA"

@pytest.mark.skipif(condition=should_skip, reason=skip_reason)
def test_case_with_cuda():
    ...
```

2. **不支持功能标记**：
```python
@pytest.mark.skip(reason="Not supported")
def test_unsupported_case():
    ...
```

3. **自定义比较逻辑**（通常不需要）：
```python
class CustomAPIBase(APIBase):
    def compare(self, name, pytorch_result, paddle_result, ...):
        # 自定义比较逻辑
        pytorch_str = str(pytorch_result).removeprefix("torch.")
        assert pytorch_str == paddle_result
```

## Step 3: 运行单元测试

在补充完测试用例后，确保能通过所有用例，请按以下命令验证执行（不可修改）：

1. 本地执行以下命令：
   ```bash
   cd /workspace/PaConvert/
   python -m pytest tests/test_<API名称>.py
   ```
2. 根据报错信息修改代码，确保所有测试用例通过

注意：每次修改 Paddle 源码后，必须重新编译方可生效。
```bash
cd /workspace/Paddle/build
cmake ..
make -j$(nproc)
```

# 三、异常处理

## 3.1 异常处理策略

在 PyTorch 对齐验证过程中，需要对不同异常情况进行分类处理。以下是异常处理策略：

### PyTorch 代码执行失败
- **错误标识**：`Failed to execute pytorch code`
- **根本原因**：PyTorch 单元测试代码存在问题，无法正常执行
- **处理策略**：修改 PyTorch 单元测试代码，确保能正确执行 Pytorch 代码
- **验证标准**：测试代码应该能够在标准的 PyTorch 环境中正常运行

### Paddle 代码执行失败
- **错误标识**：`Failed to execute paddle code`
- **根本原因**：Pytorch单测正确，但修改后的 Paddle API 实现存在问题，导致代码无法执行
- **处理策略**：需要返回到前序Step修改，因此结束本Step，将报错信息返回给主控智能体分析
- **关联任务**：Paddle API需要进一步修改以兼容 PyTorch 接口

### 计算结果不一致
- **错误标识**：`Unable to align results`
- **根本原因**：Pytorch单测正确，但Paddle API 与 PyTorch API 计算结果存在差异
- **处理策略**：需要返回到前序Step修改，因此结束本Step，将报错信息返回给主控智能体分析
- **验证要求**：Paddle API需要进一步修改以兼容 PyTorch 接口，确保数值精度、数据类型、形状等完全一致


## 3.2 常见错误及解决方案

### Paddle不支持类型提升
- 如果报错是因为 Paddle 不支持类型提升或标量输入（已知问题），可以禁用对应测试用例，其他情况不允许禁用单测：
  ```python
  # 将 def test_case_x(): 改为 def _test_case_x():
  # 并添加注释说明原因
  def _test_case_2():  # Paddle does not support scalar input
      ...
  ```
