Skip to content

Commit aef098f

Browse files
SigureMoclaude
andcommitted
[Agent] Add cross-ecosystem compatibility skill (paddle-design-compat)
New skill covering Paddle's interface compatibility system: - C++ API compat layer (at::Tensor, torch::*, c10::* → paddle) - TORCH_LIBRARY operator registration - Python torch proxy (paddle.enable_compat) - Paddle native custom op (PD_BUILD_OP, PyLayer, pybind11) - Kernel DSL ecosystem (Triton, TileLang) - Cross-ecosystem migration workflow Co-authored-by: Claude <noreply@anthropic.com>
1 parent deb5825 commit aef098f

File tree

4 files changed

+733
-0
lines changed

4 files changed

+733
-0
lines changed
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
name: paddle-design-compat
3+
description: "Use when working with Paddle's cross-ecosystem compatibility system: the PyTorch C++ API compat layer (at::Tensor, torch::*, c10::*), Python torch proxy (paddle.enable_compat), TORCH_LIBRARY operator registration, cpp_extension build system, Triton/TileLang kernel DSL integration, custom C++ operator authoring (paddle/extension.h, PD_BUILD_OP), custom Python operator (PyLayer), C++ extension (pybind11), or migrating PyTorch custom operators / third-party libraries (FlashInfer, FlashMLA, DeepGEMM etc.) to Paddle."
4+
---
5+
6+
# Paddle 接口兼容性体系
7+
8+
Paddle 3.0 提供了一套从底向上的跨生态兼容机制,使 PyTorch 生态的自定义算子库和 Kernel DSL 能以最小改动在 Paddle 中运行。同时保留了 Paddle 原生的自定义算子 / 扩展机制。
9+
10+
## 兼容性体系总览
11+
12+
```
13+
用户代码 (Python)
14+
15+
▼ Layer 4: Python API 代理层
16+
paddle.enable_compat(scope={"flashinfer"})
17+
→ import torch 被重定向至 paddle(基于 sys.meta_path 拦截)
18+
19+
▼ Layer 3: Python 接口兼容层
20+
paddle.compat 模块:兼容 PyTorch Python 组网 API(torch.ops、torch.nn 等)
21+
22+
▼ Layer 2: 算子注册兼容层
23+
TORCH_LIBRARY / TORCH_LIBRARY_IMPL 宏 → 注册到 Paddle 算子调度
24+
pybind11 注册 → 无需修改
25+
26+
▼ Layer 1: C++ API 兼容层
27+
at::Tensor / torch::* / c10::* 命名空间
28+
→ 代理到 paddle::Tensor / phi API
29+
30+
▼ Paddle 原生算子 / PHI Kernel
31+
```
32+
33+
## Layer 1: C++ API 兼容层
34+
35+
位于 `paddle/phi/api/include/compat/`,按 PyTorch 头文件结构镜像组织:
36+
37+
| 目录 | 对应 PyTorch 命名空间 | 内容 |
38+
|------|----------------------|------|
39+
| `ATen/` | `at::` | Tensor、TensorBase、ops(empty / cat / reshape …)、CUDA context |
40+
| `c10/` | `c10::` | ScalarType、Device、TensorOptions、Stream、CUDAGuard |
41+
| `torch/` | `torch::` | Library(TORCH_LIBRARY 宏)、nn::functional |
42+
| `utils/` || 类型转换工具(IntArrayRef ↔ IntArray、ScalarType ↔ DataType) |
43+
44+
核心设计:`at::Tensor` 是一个持有 `paddle::Tensor` 的代理类(参见 `ATen/core/TensorBody.h`),所有方法委托到 `paddle::Tensor`。类型相等性通过内部 paddle 对象判断。
45+
46+
## Layer 2: 算子注册兼容层
47+
48+
`torch/library.h` 提供了与 PyTorch 同名的注册宏:
49+
50+
|| 用途 |
51+
|----|------|
52+
| `TORCH_LIBRARY(ns, m)` | 定义算子 schema(如 `m.def("muladd(Tensor a, Tensor b, float c) -> Tensor")`|
53+
| `TORCH_LIBRARY_IMPL(ns, k, m)` | 注册 dispatch key 对应的实现(如 CPU、CUDA) |
54+
| `TORCH_LIBRARY_FRAGMENT(ns, m)` | 跨编译单元追加定义 |
55+
56+
注册后通过 `torch.ops.<ns>.<op_name>` 调用,代理层将调用路由到 Paddle 的算子调度。
57+
58+
## Layer 3: Python 接口兼容层
59+
60+
`python/paddle/compat/` 模块提供 PyTorch Python API 的兼容实现:
61+
62+
- `__init__.py`:兼容 `torch.sort``torch.split``torch.unique` 等函数签名差异
63+
- `nn/`:兼容 `torch.nn` 模块接口
64+
- `proxy.py`:torch proxy 核心实现
65+
66+
## Layer 4: Python API 代理层(Torch Proxy)
67+
68+
`paddle.enable_compat()` 通过 `sys.meta_path` 注入 `TorchProxyMetaFinder`,拦截 `import torch` 并重定向到 `paddle.compat`
69+
70+
```python
71+
# 全局启用
72+
paddle.enable_compat()
73+
74+
# 限定作用域(推荐)
75+
paddle.enable_compat(scope={"flashinfer", "flash_attn"})
76+
77+
# 上下文管理器
78+
with paddle.use_compat_guard():
79+
import some_torch_lib
80+
```
81+
82+
scope 限定后,仅对指定模块命名空间内的 `import torch` 生效,避免影响其他代码。
83+
84+
## Paddle 原生自定义算子机制
85+
86+
Paddle 自身也提供三种扩展方式,不依赖兼容层:
87+
88+
### 自定义 C++ 算子
89+
90+
通过 `paddle/extension.h` + `PD_BUILD_OP` 宏注册:
91+
92+
```cpp
93+
#include "paddle/extension.h"
94+
95+
std::vector<paddle::Tensor> ReluForward(const paddle::Tensor& x) {
96+
return {paddle::relu(x)};
97+
}
98+
99+
PD_BUILD_OP(custom_relu)
100+
.Inputs({"X"})
101+
.Outputs({"Out"})
102+
.SetKernelFn(PD_KERNEL(ReluForward));
103+
```
104+
105+
编译方式:
106+
- **setuptools**:`paddle.utils.cpp_extension.CppExtension` / `CUDAExtension`
107+
- **JIT**:`paddle.utils.cpp_extension.load()`
108+
109+
### 自定义 Python 算子(PyLayer)
110+
111+
```python
112+
from paddle.autograd import PyLayer
113+
114+
class CustomOp(PyLayer):
115+
@staticmethod
116+
def forward(ctx, x):
117+
ctx.save_for_backward(x)
118+
return x.exp()
119+
120+
@staticmethod
121+
def backward(ctx, grad):
122+
x, = ctx.saved_tensor()
123+
return grad * x.exp()
124+
125+
out = CustomOp.apply(input_tensor)
126+
```
127+
128+
### C++ 扩展(pybind11)
129+
130+
通过 `PYBIND11_MODULE` 直接绑定 C++ 函数到 Python,适用于非算子场景(数据处理、工具函数等)。
131+
132+
## Kernel DSL 生态
133+
134+
### Triton
135+
136+
官方 Triton 包直接支持,配合 torch proxy 即可使用:
137+
138+
```python
139+
paddle.enable_compat(scope={"triton"})
140+
import triton
141+
import triton.language as tl
142+
```
143+
144+
### TileLang
145+
146+
需安装适配版本 `tilelang-paddle`,同样通过 torch proxy 使用。
147+
148+
## 已支持的跨生态算子库
149+
150+
| 算子库 | GitHub | 说明 |
151+
|--------|--------|------|
152+
| FlashInfer | [PFCCLab/flashinfer](https://github.com/PFCCLab/flashinfer) | 注意力算子 |
153+
| FlashMLA | [PFCCLab/FlashMLA](https://github.com/PFCCLab/FlashMLA) | Multi-head Latent Attention |
154+
| DeepGEMM | [PFCCLab/DeepGEMM](https://github.com/PFCCLab/DeepGEMM) | FP8 GEMM |
155+
| DeepEP | [PFCCLab/DeepEP](https://github.com/PFCCLab/DeepEP) | Expert Parallelism 通信 |
156+
| SonicMoE | [PFCCLab/sonic-moe](https://github.com/PFCCLab/sonic-moe) | MoE 加速 |
157+
| PaddleCodec | [PFCCLab/paddlecodec](https://github.com/PFCCLab/paddlecodec) | 视频编解码 |
158+
159+
## 迁移 PyTorch 自定义算子的典型步骤
160+
161+
1. **调整构建脚本**`setup.py` 顶部添加 `import paddle; paddle.enable_compat()`,保留原 `torch.utils.cpp_extension` 调用
162+
2. **编译**`pip install . --no-build-isolation`(Paddle 的 `cpp_extension` 替代 PyTorch 版本完成编译)
163+
3. **修复 C++ 编译错误**:兼容层未覆盖的 API,通过 `_PD_*` 转换函数桥接到 Paddle C++ API
164+
4. **Python 端**:测试脚本中 `paddle.enable_compat(scope={"your_lib"})` 后直接使用
165+
166+
## 什么场景看什么文件
167+
168+
| 场景 | 参考文档 |
169+
|------|----------|
170+
| C++ 兼容层头文件结构和代理实现 | [references/cpp-compat-layer.md](references/cpp-compat-layer.md) |
171+
| Python torch proxy 和兼容 API | [references/python-compat-layer.md](references/python-compat-layer.md) |
172+
| Paddle 原生自定义算子(C++ / Python / pybind11) | [references/native-custom-op.md](references/native-custom-op.md) |
173+
174+
## 源码入口
175+
176+
### C++ 兼容层
177+
178+
| 模块 | 路径 |
179+
|------|------|
180+
| 兼容层根目录 | `paddle/phi/api/include/compat/` |
181+
| at::Tensor 代理类 | `paddle/phi/api/include/compat/ATen/core/TensorBody.h` |
182+
| c10 类型系统 | `paddle/phi/api/include/compat/c10/core/` |
183+
| TORCH_LIBRARY 注册宏 | `paddle/phi/api/include/compat/torch/library.h` |
184+
| 类型转换工具 | `paddle/phi/api/include/compat/utils/` |
185+
| torch.ops 调度实现 | `paddle/phi/api/include/compat/torch/library.cpp` |
186+
187+
### Python 兼容层
188+
189+
| 模块 | 路径 |
190+
|------|------|
191+
| paddle.enable_compat 入口 | `python/paddle/__init__.py`(别名 `enable_torch_proxy`|
192+
| Torch Proxy 核心 | `python/paddle/compat/proxy.py` |
193+
| Python API 兼容实现 | `python/paddle/compat/__init__.py` |
194+
| nn 兼容模块 | `python/paddle/compat/nn/` |
195+
196+
### Paddle 原生自定义算子
197+
198+
| 模块 | 路径 |
199+
|------|------|
200+
| extension.h 总头文件 | `paddle/extension.h` |
201+
| op_meta_info(PD_BUILD_OP) | `paddle/phi/api/ext/op_meta_info.h` |
202+
| cpp_extension 编译工具 | `python/paddle/utils/cpp_extension/cpp_extension.py` |
203+
| extension_utils | `python/paddle/utils/cpp_extension/extension_utils.py` |
204+
| PyLayer | `python/paddle/autograd/py_layer.py` |
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# C++ API 兼容层
2+
3+
## 概览
4+
5+
C++ 兼容层位于 `paddle/phi/api/include/compat/`,按 PyTorch 的头文件目录结构镜像组织,使现有 PyTorch 自定义算子 C++ 代码无需修改即可编译。
6+
7+
核心思路:为 PyTorch 的命名空间(`at::``torch::``c10::`)提供同名类和函数,内部委托到 Paddle 对应的 C++ API。
8+
9+
## 目录结构
10+
11+
```
12+
paddle/phi/api/include/compat/
13+
├── ATen/
14+
│ ├── core/
15+
│ │ ├── TensorBody.h ← at::Tensor 代理类核心
16+
│ │ ├── TensorBase.h ← TensorBase 基类,持有 paddle::Tensor
17+
│ │ ├── Scalar.h ← at::Scalar → paddle::Scalar
18+
│ │ ├── TensorAccessor.h ← data accessor
19+
│ │ ├── Generator.h ← 随机数生成器兼容
20+
│ │ └── ivalue.h ← IValue 容器(用于 TORCH_LIBRARY schema 解析)
21+
│ ├── cuda/
22+
│ │ ├── CUDAContext.h ← at::cuda::getCurrentCUDAStream 等
23+
│ │ ├── CUDAStream.h ← CUDA stream 封装
24+
│ │ ├── CUDAEvent.h ← CUDA event 封装
25+
│ │ ├── CUDAGuard.h ← 设备切换守卫
26+
│ │ ├── CUDADataType.h ← CUDA 数据类型映射
27+
│ │ ├── EmptyTensor.h/cpp ← CUDA 下的 empty tensor 创建
28+
│ │ └── PhiloxCudaState.h ← Philox RNG 状态
29+
│ ├── ops/
30+
│ │ ├── empty.h ← at::empty()
31+
│ │ ├── full.h ← at::full()
32+
│ │ ├── ones.h / zeros.h ← at::ones() / at::zeros()
33+
│ │ ├── cat.h ← at::cat()
34+
│ │ ├── reshape.h ← at::reshape()
35+
│ │ ├── slice.h / select.h ← at::slice() / at::select()
36+
│ │ ├── to.h ← at::Tensor::to()
37+
│ │ └── ... (60+ ops)
38+
│ ├── native/
39+
│ │ └── cuda/Resize.h
40+
│ ├── ATen.h ← 顶层聚合头
41+
│ ├── Device.h
42+
│ ├── DeviceGuard.h
43+
│ ├── Functions.h
44+
│ ├── Tensor.h
45+
│ ├── TensorIndexing.h
46+
│ └── Utils.h/cpp
47+
├── c10/
48+
│ ├── core/
49+
│ │ ├── ScalarType.h ← c10::ScalarType 枚举(映射到 phi::DataType)
50+
│ │ ├── Device.h/cpp ← c10::Device(映射到 phi::Place)
51+
│ │ ├── TensorOptions.h ← c10::TensorOptions(dtype + device + layout)
52+
│ │ ├── Stream.h/cpp ← c10::Stream
53+
│ │ ├── Storage.h ← c10::Storage
54+
│ │ ├── Layout.h ← c10::Layout
55+
│ │ ├── MemoryFormat.h
56+
│ │ ├── DispatchKey.h ← dispatch key 枚举(CPU / CUDA 等)
57+
│ │ ├── Scalar.h ← c10::Scalar
58+
│ │ └── Allocator.h
59+
│ ├── cuda/
60+
│ │ ├── CUDAStream.h ← c10::cuda::CUDAStream
61+
│ │ ├── CUDAGuard.h ← c10::cuda::CUDAStreamGuard
62+
│ │ ├── CUDAFunctions.h ← c10::cuda::device_count() 等
63+
│ │ └── CUDAException.h
64+
│ ├── macros/Macros.h ← C10_CONCATENATE 等宏
65+
│ └── util/accumulate.h
66+
├── torch/
67+
│ ├── library.h/cpp ← TORCH_LIBRARY / TORCH_LIBRARY_IMPL 宏
68+
│ ├── extension.h ← torch/extension.h 入口
69+
│ └── csrc/api/include/torch/
70+
│ ├── all.h
71+
│ ├── cuda.h/cpp
72+
│ ├── python.h
73+
│ ├── types.h
74+
│ ├── sparse.h
75+
│ └── nn/functional.h
76+
├── utils/
77+
│ ├── scalar_type_conversion.h ← ScalarType ↔ phi::DataType
78+
│ ├── int_array_ref_conversion.h ← IntArrayRef ↔ IntArray
79+
│ ├── dense_sparse_conversion.h ← 稀疏张量转换
80+
│ ├── pinned_place.h
81+
│ └── macros.h
82+
├── CMakeLists.txt
83+
└── README.md
84+
```
85+
86+
## at::Tensor 代理类
87+
88+
核心设计在 `ATen/core/TensorBody.h`
89+
90+
```cpp
91+
namespace at {
92+
using PaddleTensor = paddle::Tensor;
93+
94+
class Tensor : public TensorBase {
95+
public:
96+
// TensorBase 内部持有 paddle::Tensor tensor_
97+
Tensor(const PaddleTensor& tensor) : TensorBase(tensor) {}
98+
99+
// 方法委托到 paddle::Tensor
100+
void* data_ptr() const { return const_cast<void*>(tensor_.data()); }
101+
c10::IntArrayRef sizes() const { ... } // dims() → IntArrayRef
102+
int64_t numel() const { return tensor_.numel(); }
103+
c10::ScalarType dtype() const { ... } // phi::DataType → ScalarType
104+
c10::Device device() const { ... } // Place → Device
105+
106+
// 内部桥接接口
107+
PaddleTensor _PD_GetInner() const { return tensor_; }
108+
};
109+
} // namespace at
110+
```
111+
112+
所有 `at::Tensor` 上的方法最终调用 `paddle::Tensor` 或 `paddle::experimental::*` 的 C++ API。
113+
114+
## 类型转换工具
115+
116+
`utils/` 目录提供双向转换函数:
117+
118+
| 函数 | 转换方向 |
119+
|------|----------|
120+
| `_PD_AtenScalarTypeToPhiDataType()` | `c10::ScalarType` → `phi::DataType` |
121+
| `_PD_PhiDataTypeToAtenScalarType()` | `phi::DataType` → `c10::ScalarType` |
122+
| `_PD_PhiDDimToIntArrayRef()` | `phi::DDim` → `c10::IntArrayRef` |
123+
| `IntArrayRef::_PD_ToPaddleIntArray()` | `c10::IntArrayRef` → `paddle::IntArray` |
124+
| `TensorOptions::_PD_GetPlace()` | `c10::TensorOptions` → `phi::Place` |
125+
126+
命名约定:所有 Paddle 扩展的转换函数以 `_PD_` 前缀标识。
127+
128+
## TORCH_LIBRARY 算子注册
129+
130+
`torch/library.h` 实现了 PyTorch 的算子注册宏:
131+
132+
```cpp
133+
// 定义算子 schema
134+
TORCH_LIBRARY(my_ops, m) {
135+
m.def("muladd(Tensor a, Tensor b, float c) -> Tensor");
136+
}
137+
138+
// 注册 CPU 实现
139+
TORCH_LIBRARY_IMPL(my_ops, CPU, m) {
140+
m.impl("muladd", &muladd_cpu);
141+
}
142+
```
143+
144+
实现原理:
145+
1. `TORCH_LIBRARY` 宏展开为 static 初始化器,构造 `torch::Library` 对象
146+
2. `Library::def()` 解析函数签名字符串,记录 schema
147+
3. `Library::impl()` 注册函数指针到 dispatch table
148+
4. Python 端 `torch.ops.<ns>.<name>` 查找并调用注册的实现
149+
150+
## 常见编译问题
151+
152+
| 错误 | 原因 | 解决方式 |
153+
|------|------|----------|
154+
| `'empty' is not a member of 'torch'` | 兼容层未实现该 op |`_PD_*` 转换 + `paddle::experimental::empty()` |
155+
| `'ScalarType' has no member 'Half'` | 枚举值名称差异 | 检查 `c10/core/ScalarType.h` 中的映射 |
156+
| `cannot convert 'at::Tensor' to 'paddle::Tensor'` | 需要显式解包 | 使用 `tensor._PD_GetInner()` |
157+
| `undefined reference to 'at::*'` | 缺少 `.cpp` 文件链接 | 确保 CMakeLists 包含 compat 目录 |
158+
159+
## 关键源码路径
160+
161+
| 文件 | 说明 |
162+
|------|------|
163+
| `paddle/phi/api/include/compat/ATen/core/TensorBody.h` | at::Tensor 代理类定义 |
164+
| `paddle/phi/api/include/compat/ATen/core/TensorBase.h` | 基类,持有 paddle::Tensor |
165+
| `paddle/phi/api/include/compat/ATen/ops/*.h` | 各个 at::ops 的兼容实现 |
166+
| `paddle/phi/api/include/compat/c10/core/ScalarType.h` | 数据类型枚举映射 |
167+
| `paddle/phi/api/include/compat/c10/core/Device.h` | 设备类型映射 |
168+
| `paddle/phi/api/include/compat/c10/core/TensorOptions.h` | TensorOptions 兼容 |
169+
| `paddle/phi/api/include/compat/torch/library.h` | TORCH_LIBRARY 宏实现 |
170+
| `paddle/phi/api/include/compat/torch/library.cpp` | Library 类方法实现 |
171+
| `paddle/phi/api/include/compat/utils/scalar_type_conversion.h` | ScalarType 双向转换 |
172+
| `paddle/phi/api/include/compat/utils/int_array_ref_conversion.h` | IntArrayRef 双向转换 |

0 commit comments

Comments
 (0)