Skip to main content

compatibility-test

负责《Paddle API 对齐 PyTorch 项目》中 Step3 兼容测试,为已修改的 Paddle API 添加兼容性单测并执行验证,确保 API 的 Paddle 用法与 PyTorch 用法均能正常工作。

Source facts

Repository
PaddlePaddle/docs
Last source activity
June 26, 2026 at 08:08
Detected SKILL.md language
Chinese
Stars
284
Forks
904

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
compatibility-test
description
负责《Paddle API 对齐 PyTorch 项目》中 Step3 兼容测试,为已修改的 Paddle API 添加兼容性单测并执行验证,确保 API 的 Paddle 用法与 PyTorch 用法均能正常工作。
disable-model-invocation
false
# 一、标准工作流程 ## Step 1:编写测试用例 在 `${ROOT_DIR}/Paddle/test/legacy_test/` 目录下找到 `test_api_compatibility[1-9]\.py` 中数字最大的文件,在该文件中添加测试。 严格按以下模板编写测试类: ### 测试模板 ```python class Test<APIName>API(unittest.TestCase): def setUp(self): # If not use random seed, remove setUp np.random.seed(2025) self.np_x = np.random.rand(...).astype(...) def test_dygraph_Compatibility(self): paddle.disable_static() x = paddle.to_tensor(self.np_x) # 1. Paddle Positional arguments out1 = paddle.<api_name>(x, ...) # 2. Paddle keyword arguments out2 = paddle.<api_name>(x=x, ...) # 3. Pytorch Positional arguments (only if order different with paddle args) out3 = paddle.<api_name>(x, ...) # 4. PyTorch keyword arguments (alias) out4 = paddle.<api_name>(input=x, dim=...) # 5. Mixed arguments out5 = paddle.<api_name>(x, axis=...) # 6. out parameter test (only if supported) out6 = paddle.empty_like(x) out7 = paddle.<api_name>(x, ..., out=out6) # 7. Tensor method - args (only if supported) out8 = x.<api_name>(...) # 8. Tensor method - kwargs (only if supported) out9 = x.<api_name>(axis=...) # Verify all outputs for out in [out1, out2, out3, out4, out5, out6, out7, out8, out9]: np.testing.assert_allclose(out.numpy(), ...) paddle.enable_static() def test_static_Compatibility(self): paddle.enable_static() main = paddle.static.Program() startup = paddle.static.Program() with paddle.static.program_guard(main, startup): x = paddle.static.data(name="x", shape=self.shape, dtype=self.dtype) # Create multiple outputs out1 = paddle.<api_name>(x, ...) out2 = paddle.<api_name>(x=x, ...) out3 = paddle.<api_name>(input=x, dim=...) exe = paddle.static.Executor() fetches = exe.run( main, feed={"x": self.np_x}, fetch_list=[out1, out2, out3], ) # Verify all outputs for out in fetches: np.testing.assert_allclose(out, ...) ``` ### 测试规范 **动态图模式必测项**: 1. ✅ Paddle 位置参数(全部位置参数) 2. ✅ Paddle 关键字参数(全部关键字参数) 3. ✅ PyTorch 位置参数(如果 PyTorch 与 Paddle 参数顺序不同) 4. ✅ PyTorch 关键字参数(使用参数别名) 5. ✅ 混合参数(如果参数量>=2,位置+关键字) 6. ✅ out 参数(如果 API 支持,inplace API 无需测) 7. ✅ 类方法 PyTorch 位置参数(如果有类方法) 8. ✅ 类方法 PyTorch 关键字参数(如果有类方法) **静态图模式必测项**(inplace API 无需测): 1. ✅ Paddle 位置参数(全部位置参数) 2. ✅ Paddle 关键字参数(全部关键字参数) 3. ✅ PyTorch 位置参数(如果 PyTorch 与 Paddle 参数顺序不同) 4. ✅ PyTorch 关键字参数(使用参数别名) 5. ✅ 类方法 PyTorch 位置参数(如果有类方法) 6. ✅ 类方法 PyTorch 关键字参数(如果有类方法) ### 测试注意事项 1. **可选测试项判断**:根据 API 实际支持的用法判断是否需要添加对应测试项 2. **顺序要求**:添加测试项需遵循上述顺序,不要打乱 3. **输出编号连贯**:输出结果序号需要保持连贯,每个输出结果均需检验 4. **避免重复**:对于内容相同的测试项,不要重复添加 5. **inplace API 特殊处理**:inplace API 只需测试动态图,无需测试静态图 ### 特殊参数测试 **pin_memory 参数测试**: ```python if paddle.device.is_compiled_with_cuda() or paddle.device.is_compiled_with_xpu(): x = paddle.xxx([2], device="gpu", pin_memory=True) self.assertTrue("pinned" in str(x.place)) ``` **device 参数测试**: ```python # 测试不同设备 if paddle.device.is_compiled_with_cuda(): out_cpu = paddle.<api_name>(x, device="cpu") out_gpu = paddle.<api_name>(x, device="gpu:0") ``` ## Step 2:编译并运行单测(每次修改代码均需执行编译) 单测编写完成后,按以下命令验证执行: ```bash cd ${ROOT_DIR}/Paddle/build cmake .. && make -j$(nproc) > compile.log 2>&1 python test_xxx.py ``` 根据报错信息修改测试用例或回退,确保所有测试用例通过。每次修改后均需要重新执行本步骤。 **编译注意事项**: - 无需重装,直接生效(勿执行 setup/install 等安装操作) - 勿删除 build 目录(否则增量编译失效,编译时间极长) # 二、技术背景知识 ### 测试框架说明 - **unittest**:Python 标准库测试框架,本步骤采用该框架 - **动态图测试**:通过 `paddle.disable_static()` 和 `paddle.enable_static()` 切换模式 - **静态图测试**:通过 `paddle.static.program_guard` 创建程序上下文 ### 常用断言方法 ```python # 数值比对 np.testing.assert_allclose(actual, expected, rtol=1e-5, atol=1e-8) np.testing.assert_array_equal(actual, expected) # 布尔断言 self.assertTrue(condition) self.assertFalse(condition) self.assertEqual(a, b) self.assertIsInstance(obj, cls) ``` ### 测试数据生成 ```python # 随机数据 np.random.seed(2025) self.np_x = np.random.rand(2, 3).astype(np.float32) # 特定形状 self.shape = [2, 3, 4] self.dtype = np.float32 ``` # 三、注意事项 1. 严格按标准工作流程执行,杜绝自行臆断和跳过步骤 2. `${ROOT_DIR}` 变量表示根目录,需自行替换为实际路径,若未通过 ROOT_DIR 指定,则均为相对于 ROOT_DIR 的路径 3. 不要新建测试文件,直接在已有的 `test_api_compatibility[1-9]\\.py` 中添加 4. 测试类命名遵循 `Test<APIName>API` 格式,如 `TestArgmaxAPI` 5. 确保测试覆盖所有新增的参数别名和参数用法 6. 代码测试覆盖率要求:务必要确保新增所有代码行数都能够在单测中跑到,否则无法通过 CI 检查 # 四、异常回退原则 当本步骤多次尝试仍无法通过时,需要根据错误信息诊断问题根源: 1. **若判断为测试用例编写有误**(如断言逻辑错误、测试数据错误): - 直接在本步骤修正测试用例 - 无需回退到其他步骤 2. **若判断为代码实现有误**(如参数处理逻辑错误、类型转换失败等): - 回退到总步骤 Step2(代码修改)调整实现方式 - 回退后再进入本步骤(Step3),则只需执行:编译并运行,其他步骤无需执行 3. **若判断为方案选择错误**(如当前方案不适用、底层不支持等): - 回退到总步骤 Step1(选择方案)重新选择 - 回退后再进入本步骤(Step3),则只需执行:编译并运行,其他步骤无需执行 # 五、常见问题处理 ### Q1:测试报错 "unexpected keyword argument" **错误现象**: ``` TypeError: xxx() got an unexpected keyword argument 'out' ``` **解决方法**: 检查 API 签名是否正确添加了 out 参数,或参数名是否拼写正确。 ### Q2:pin_memory 测试报错 "Pinning memory is not supported" **错误现象**: ``` RuntimeError: Pinning memory is not supported for Place(cpu) ``` **解决方法**: `pin_memory=True` 仅在 GPU/XPU 设备上有意义。确保测试逻辑中正确添加了环境判断: ```python if paddle.device.is_compiled_with_cuda() or paddle.device.is_compiled_with_xpu(): x = paddle.xxx([2], device="gpu", pin_memory=True) self.assertTrue("pinned" in str(x.place)) ``` ### Q3:静态图测试失败 "object has no attribute" **错误现象**: ``` AttributeError: 'OpResult' object has no attribute 'pin_memory' ``` **解决方法**: 某些动态图专用的方法需要在 `in_dynamic_mode()` 保护下执行: ```python if in_dynamic_mode(): tensor = tensor.pin_memory() ``` ### Q4:数值比对失败 **错误现象**: ``` AssertionError: Not equal to tolerance rtol=1e-5, atol=1e-8 ``` **解决方法**: 1. 检查输入数据是否正确生成 2. 检查预期输出值是否正确 3. 适当调整容差参数 `rtol` 和 `atol`
View on GitHub