一、ATen 是什么?在 PyTorch 中扮演什么角色?
当你在 Python 中写下 torch.add(a, b) 或 a.cos() 时,最终执行计算的不是 Python,而是一套 C++ 库------这就是 ATen(A Tensor Library)。
ATen 在 PyTorch 整体架构中的位置如下:
┌─────────────────────────────────────────────┐
│ Python API 层(torch/, torch.nn, ...) │
├─────────────────────────────────────────────┤
│ Python-C++ 绑定层(torch/csrc/) │
├─────────────────────────────────────────────┤
│ ★ ATen(aten/src/ATen/) │ ← 本文分析目标
│ ├─ 算子声明(native_functions.yaml) │
│ ├─ 算子实现(native/) │
│ ├─ 核心抽象(Tensor, TensorIterator, ...) │
│ ├─ 设备后端(cpu/, cuda/, mps/, ...) │
│ └─ 代码生成模板(templates/) │
├─────────────────────────────────────────────┤
│ c10 核心库(c10/) │
│ ├─ Storage, TensorImpl, DispatchKey │
│ └─ Allocator, Device, ScalarType │
└─────────────────────────────────────────────┘
一句话总结 :c10 提供最底层的张量存储和分发基础设施,ATen 在其之上实现了 1000+ 个算子 的具体逻辑,而 Python 层只是这些 C++ 实现的薄封装。
二、aten/ 目录全景
aten/
├── CMakeLists.txt # 构建入口
├── tools/ # 代码生成辅助工具
└── src/
├── README.md # 历史说明(TH/THC 的演变)
├── THC/ # 遗留的 CUDA 辅助代码
└── ATen/ # ★ 核心所在
├── native/ # ★★★ 算子实现(最大的子目录)
├── core/ # 核心抽象(移动端友好)
├── cpu/ # CPU 向量化支持
├── cuda/ # CUDA 运行时支持
├── detail/ # 设备钩子接口
├── functorch/ # vmap/grad 批处理规则
├── ops/ # 代码生成的算子绑定
├── templates/ # 代码生成模板
├── quantized/ # 量化相关
├── cudnn/ # cuDNN 封装
├── miopen/ # MIOpen (AMD) 封装
├── mps/ # Apple Metal 封装
├── mkl/ # Intel MKL 封装
├── vulkan/ # Vulkan 移动端后端
├── metal/ # Metal 移动端后端
├── xpu/ # Intel GPU 后端
├── test/ # C++ 单元测试
├── benchmarks/ # 性能基准
└── *.h / *.cpp # 顶层核心头文件与实现
三、核心中的核心:native_functions.yaml
如果说 ATen 有一个"上帝文件",那就是 aten/src/ATen/native/native_functions.yaml。PyTorch 的 每一个 原生算子都在这个 YAML 文件中声明。
3.1 格式解析
一个典型的算子声明长这样:
yaml
- func: add.Tensor(Tensor self, Tensor other, *, Scalar alpha=1) -> Tensor
variants: function, method
dispatch:
CPU: add_cpu
CUDA: add_cuda
SparseCPU: add_sparse
SparseCUDA: add_sparse_cuda
MPS: add_mps
它声明了以下信息:
| 字段 | 含义 |
|---|---|
func |
算子签名(名称、参数类型、默认值、返回类型) |
variants |
生成 at::add() 函数和 Tensor::add() 方法 |
dispatch |
不同设备/后端对应的 C++ 实现函数名 |
3.2 代码生成流程
当你修改了 native_functions.yaml,PyTorch 的构建系统(torchgen/)会:
native_functions.yaml
│
▼
torchgen/ 代码生成器
│
├─→ aten/src/ATen/ops/ # 生成的 C++ 绑定
│ ├─ Functions.h # at::add() 声明
│ ├─ TensorBody.h # Tensor::add() 方法
│ ├─ Operators.cpp # 分发桩代码
│ └─ RegisterSchema.cpp # Schema 注册
│
├─→ torch/csrc/autograd/ # 生成的 Python 绑定
│
└─→ build/aten/src/ATen/ # 构建产物
这意味着:开发者增加新算子的第一步不是写 C++ 代码,而是先在 YAML 中声明签名。
3.3 三种 Dispatch 关键字
dispatch 字段的值决定了算子的实现策略,这是 ATen 设计哲学的精髓:
| Dispatch 关键字 | 语义 | 适用场景 |
|---|---|---|
CompositeImplicitAutograd |
由其他算子组合而成,自动推导梯度 | 可分解的高层算子(如 addcmul) |
CompositeExplicitAutograd |
由其他算子组合,但需手写梯度 (在 derivatives.yaml) |
需要自定义反向传播的委托函数 |
CPU / CUDA / MPS / ... |
设备特化实现 | 需要针对特定硬件优化的算子 |
设计哲学 :如果一个算子能用已有算子组合实现,就用 CompositeImplicitAutograd,让 autograd 自动推导梯度。只有性能或数值精度不满足时,才下降到设备特化实现。
四、native/ 目录:算子实现的主战场
aten/src/ATen/native/ 是整个 ATen 中 最庞大 的目录,包含数百个算子的 C++ 实现。
4.1 顶层分类
native/ 下的文件按算子类别组织:
| 文件/文件组 | 涵盖算子 |
|---|---|
UnaryOps.cpp |
abs, cos, sin, exp, log, sqrt, ... |
BinaryOps.cpp |
add, sub, mul, div, ... |
ReduceOps.cpp |
sum, mean, prod, max, min, ... |
TensorShape.cpp |
reshape, view, permute, transpose, cat, stack, ... |
TensorFactories.cpp |
zeros, ones, empty, rand, randn, arange, ... |
TensorCompare.cpp |
eq, ne, lt, gt, where, ... |
TensorAdvancedIndexing.cpp |
index, index_put, gather, scatter, ... |
LinearAlgebra.cpp |
mm, bmm, addmm, svd, qr, ... |
Convolution.cpp |
conv1d, conv2d, conv3d + 路由逻辑 |
Normalization.cpp |
batch_norm, layer_norm, group_norm, ... |
Activation.cpp |
relu, gelu, silu, hardswish, ... |
Loss.cpp / LossCTC.cpp |
cross_entropy, nll_loss, ctc_loss, ... |
SoftMax.cpp |
softmax, log_softmax |
Pooling.cpp |
max_pool, avg_pool, adaptive_pool, ... |
Embedding.cpp |
embedding, embedding_bag |
Distributions.cpp |
normal_, uniform_, bernoulli_, ... |
RNN.cpp |
lstm, gru 计算内核 |
Copy.cpp |
tensor 间的拷贝逻辑 |
Resize.cpp |
张量尺寸调整 |
4.2 设备后端子目录
native/ 下有多个设备特化的子目录:
native/
├── cpu/ # CPU 向量化内核(AVX2/AVX512/NEON/SVE 多版本编译)
├── cuda/ # CUDA 内核(.cu 文件,约 300+ 个)
├── mps/ # Apple Metal 内核(.mm 文件)
├── mkldnn/ # Intel oneDNN 加速内核
├── cudnn/ # cuDNN 加速(卷积、BN、RNN)
├── miopen/ # AMD MIOpen 加速
├── xnnpack/ # ARM CPU XNNPACK 加速(移动端)
├── sparse/ # 稀疏张量操作
├── nested/ # 嵌套张量操作
├── quantized/ # 量化算子
├── transformers/ # Attention 实现(FlashAttention/高效注意力)
├── vulkan/ # Vulkan 移动端 GPU
└── kleidiai/ # ARM KleidiAI 加速
4.3 CPU 内核的多版本编译机制
native/cpu/ 目录下的文件有一个非常特殊的编译策略 :每个 .cpp 文件会被编译 多次 ,每次使用不同的指令集标志(如 -mavx2、-mavx512f)。
BinaryOpsKernel.cpp
│
├─ 编译为 BinaryOpsKernel_DEFAULT.o (基础 SSE)
├─ 编译为 BinaryOpsKernel_AVX2.o (-mavx2 -mfma)
└─ 编译为 BinaryOpsKernel_AVX512.o (-mavx512f -mavx512bw)
运行时通过 DispatchStub 机制根据 CPU 特性自动选择最优版本:
cpp
// 在 native/BinaryOps.h 中声明
DECLARE_DISPATCH(add_fn, add_stub);
// 在 native/BinaryOps.cpp 中定义
DEFINE_DISPATCH(add_stub);
// 在 native/cpu/BinaryOpsKernel.cpp 中注册
REGISTER_DISPATCH(add_stub, &add_kernel);
关键约束(来自 README):
native/cpu/中的所有实现必须放在匿名命名空间中,否则不同指令集版本的符号会在链接时冲突。- 只有需要利用 SIMD 指令的计算密集型内核才应放在
native/cpu/。
4.4 CUDA 内核的组织
native/cuda/ 包含约 300+ 个 .cu 文件,是 ATen 中第二大的代码区。
组织特点:
native/cuda/
├── UnaryOpsKernel.cu # 一元操作
├── BinaryMulKernel.cu # 二元操作(按类型拆分)
├── BinaryDivTrueKernel.cu
├── ReduceSumProdKernel.cu # 归约操作
├── SortStable.cu # 排序
├── Indexing.cu # 索引
├── Embedding.cu # 嵌入
├── SpectralOps.cu # FFT
├── fused_adam_impl.cu # 融合优化器
├── fused_adamw_impl.cu
├── int4mm.cu # 量化矩阵乘
├── int8mm.cu
├── RowwiseScaledMM.cu # 逐行缩放 GEMM
├── ScaledGroupMM.cu # 缩放分组 GEMM
├── cutlass_extensions/ # CUTLASS 扩展模板
├── linalg/ # CUDA 线性代数
├── tunable/ # 自动调优框架
└── jit_utils.cpp # CUDA JIT 编译工具
每个 CUDA 内核通常使用以下模式之一:
- TensorIterator + gpu_kernel:用于逐元素操作,自动处理广播和类型提升。
- 手写 CUDA kernel:用于无法用 TensorIterator 表达的复杂操作(如 sort、scatter)。
- 调用外部库:cuBLAS(GEMM)、cuDNN(卷积/BN)、cuSOLVER(SVD/QR)等。
五、核心基础设施
5.1 TensorIterator --- 逐元素操作的瑞士军刀
TensorIterator(声明在 ATen/TensorIterator.h)是 ATen 中使用最广泛的基础设施 ,灵感来自 NumPy 的 NpyIter。
它自动处理:
- 广播(broadcasting)
- 类型提升(type promotion)
- 内存连续性优化
- 多线程并行
使用模式:
cpp
// 配置
auto iter = TensorIteratorConfig()
.add_output(output)
.add_input(input_a)
.add_input(input_b)
.build();
// CPU 内核
cpu_kernel(iter, [](float a, float b) -> float {
return a + b;
});
// CUDA 内核
gpu_kernel(iter, []GPU_LAMBDA(float a, float b) -> float {
return a + b;
});
为什么重要:绝大多数逐元素和归约算子(add、mul、cos、sum......)都通过 TensorIterator 实现。它将"算子业务逻辑"和"内存遍历/并行策略"彻底解耦。
5.2 AT_DISPATCH 宏 --- 类型分发
PyTorch 支持 20+ 种数据类型(float16/32/64, int8/16/32/64, bfloat16, complex64/128, ...)。C++ 模板不能直接用 runtime 的 ScalarType 实例化,因此 ATen 使用 AT_DISPATCH_* 宏族做类型分发:
cpp
AT_DISPATCH_ALL_TYPES_AND2(
kHalf, kBFloat16,
input.scalar_type(),
"my_kernel",
[&]() {
// scalar_t 在这里被绑定为具体类型
cpu_kernel(iter, [](scalar_t a) -> scalar_t {
return a * a;
});
}
);
常用宏包括:
AT_DISPATCH_ALL_TYPES--- float/double/int8/16/32/64AT_DISPATCH_FLOATING_TYPES--- float/doubleAT_DISPATCH_ALL_TYPES_AND(kHalf, ...)--- 增加 float16AT_DISPATCH_ALL_TYPES_AND_COMPLEX--- 包含 complex64/128
5.3 DispatchStub --- CPU 指令集分发
如前所述,DispatchStub 是 CPU 多版本编译的分发机制:
DispatchStub<fn_type, impl>
│
├─ DEFAULT → 基础实现
├─ AVX2 → AVX2 优化实现
└─ AVX512 → AVX512 优化实现
支持的设备类型不限于 CPU,还包括 CUDA、HIP、MPS、XPU 等。运行时根据 cpuinfo 报告的 CPU 特性自动选择最优路径。
5.4 向量化库 cpu/vec/
ATen/cpu/vec/ 提供了跨平台的 SIMD 向量化抽象:
cpu/vec/
├── vec.h # 统一入口
├── vec_base.h # 标量回退实现
├── vec256/ # 256-bit 向量(AVX2/NEON)
│ ├── vec256_float.h
│ ├── vec256_int.h
│ └── ...
├── vec512/ # 512-bit 向量(AVX512)
├── vec128/ # 128-bit 向量(SSE/NEON)
├── sve/ # ARM SVE 支持
├── functional.h # map/reduce 等函数式接口
├── vec_convert.h # 类型转换
└── vec_mask.h # 掩码操作
Vectorized<T> 模板类封装了不同 SIMD 指令集的寄存器操作,让算子开发者可以写出一次编写、多指令集运行的代码:
cpp
#include <ATen/cpu/vec/vec.h>
using namespace at::vec;
void my_fast_cos(float* out, const float* in, int64_t n) {
int64_t d = 0;
for (; d < n - (n % Vectorized<float>::size()); d += Vectorized<float>::size()) {
auto x = Vectorized<float>::loadu(in + d);
x.cos().store(out + d);
}
for (; d < n; d++) {
out[d] = std::cos(in[d]);
}
}
六、core/ 目录:移动端友好的核心抽象
ATen/core/ 包含 ATen 的最小内核子集,经过精心设计以控制二进制体积,适合移动端部署。
core/
├── Tensor.h / Tensor.cpp # Tensor 核心定义
├── TensorBase.h # Tensor 基类(无 autograd)
├── Generator.h # 随机数生成器抽象
├── Dimname.h # 命名维度
├── ivalue.h # IValue(JIT 系统的通用值类型)
├── function_schema.h # 算子签名描述
├── op_registration/ # 算子注册基础设施
├── dispatch/ # 分发器核心
├── boxing/ # 装箱/拆箱(泛型调用)
├── class_type.h / custom_class.h # TorchScript 自定义类
├── List.h / Dict.h # 泛型容器
└── PythonFallbackKernel.cpp # Python 回调内核
关键设计约束(来自 README):
二进制大小是此目录中文件的重要约束。
这意味着 core/ 中的代码不能随意添加重型依赖。
七、CUDA 运行时支持:cuda/ 目录
ATen/cuda/ 不是算子实现(那在 native/cuda/),而是 CUDA 运行时基础设施:
ATen/cuda/
├── CUDAContext.h/.cpp # CUDA 上下文管理(当前设备、stream)
├── CUDABlas.h/.cpp # cuBLAS 封装(GEMM、BatchedGEMM)
├── CUDASparseBlas.h/.cpp # cuSPARSE 封装
├── CUDAGraph.h/.cpp/.cu # CUDA Graph 录制与回放
├── CUDAGeneratorImpl.h/.cpp # CUDA 随机数生成器
├── CUDAEvent.h # CUDA Event 封装
├── CachingHostAllocator.h # 页锁定内存缓存分配器
├── MemPool.h/.cpp # 内存池管理
├── PeerToPeerAccess.h/.cpp # 多 GPU P2P 访问
├── Atomic.cuh # 原子操作
├── cub.cuh # CUB 库封装(排序、扫描)
├── PhiloxCudaState.h # Philox 随机数状态
├── tunable/ # 自动调优框架
├── detail/ # 内部实现细节
└── nvrtc_stub/ # NVRTC JIT 编译桩
CUDABlas 是一个重要的性能热点封装,它包装了 cuBLAS 的 GEMM 调用,并在内部处理:
- Tensor Core 的自动使用
- workspace 管理
- 混合精度支持(FP16/BF16 GEMM + FP32 累加)
八、detail/ 目录:设备钩子架构
ATen/detail/ 定义了 PyTorch 的 设备钩子接口(Hooks Interface),这是支持多后端可扩展性的关键:
detail/
├── CUDAHooksInterface.h # CUDA 后端钩子
├── HIPHooksInterface.h # ROCm/HIP 后端钩子
├── MPSHooksInterface.h # Apple Metal 后端钩子
├── XPUHooksInterface.h # Intel GPU 后端钩子
├── MTIAHooksInterface.h # Meta AI 加速器钩子
├── HPUHooksInterface.h # Intel Gaudi 钩子
├── PrivateUse1HooksInterface.h# 自定义设备钩子
├── AcceleratorHooksInterface.h# 加速器通用接口
├── XLAHooksInterface.h # XLA 后端钩子
└── CPUGuardImpl.cpp # CPU 设备守卫
设计模式 :每个 XxxHooksInterface.h 定义了一组虚函数(如 getDeviceCount()、getStream()),对应后端在自己的库中提供具体实现,通过动态链接注册到 ATen。
这使得核心 ATen 库不需要链接任何设备特定库即可编译,设备支持是"插件式"的。
九、代码生成系统:templates/ 与 ops/
9.1 templates/ --- 代码模板
templates/
├── TensorBody.h # Tensor 类方法声明模板
├── TensorMethods.cpp # Tensor 类方法实现模板
├── Functions.h # at:: 命名空间函数声明
├── Functions.cpp # 函数实现
├── Operators.h/.cpp # 分发桩
├── RegisterSchema.cpp # Schema 注册
├── RegisterDispatchKey.cpp # 各 DispatchKey 注册
├── NativeFunctions.h # Native 函数声明
├── DispatchKeyFunctions.h # 按 key 的函数声明
└── RegisterFunctionalization.cpp # 功能化变换注册
这些模板通过 torchgen/ 代码生成器填充,产出到 build/aten/src/ATen/ 目录。
9.2 ops/ --- 生成产物(仓库中只有少量文件)
ops/
├── tensor.h # 简便头文件
└── from_blob.h # from_blob 工厂函数
构建后,ops/ 目录会包含每个算子的独立头文件(如 ops/add.h),是面向用户的 C++ API 入口。
十、专项领域模块
10.1 native/transformers/ --- 注意力机制
native/transformers/
├── attention.h/.cpp # 统一注意力入口
├── sdp_utils_cpp.h/.cpp # Scaled Dot Product Attention 工具
├── transformer.cpp # 整体 Transformer 组件
├── cuda/ # FlashAttention / Memory-Efficient Attention
├── hip/ # AMD GPU 注意力实现
└── xpu/ # Intel GPU 注意力实现
这是近年来 PyTorch 性能提升最显著的模块之一,封装了 FlashAttention v1/v2、Memory-Efficient Attention 等高效实现。
10.2 native/sparse/ --- 稀疏张量
native/sparse/
├── SparseTensor.cpp # COO 格式稀疏张量操作
├── SparseTensorMath.cpp # 稀疏数学运算
├── SparseCsrTensor.cpp # CSR/CSC/BSR/BSC 格式
├── SparseFactories.cpp # 稀疏张量工厂函数
├── SparseBlas.cpp # 稀疏 BLAS
├── cuda/ # CUDA 稀疏实现
├── mps/ # Metal 稀疏实现
└── eigen/ # Eigen 库方案
10.3 native/nested/ --- 嵌套张量
native/nested/
├── NestedTensorUtils.h/.cpp # 核心工具
├── NestedTensorMath.cpp # 数学操作
├── NestedTensorMatmul.cpp # 矩阵乘
├── NestedTensorTransformerFunctions.cpp # Transformer 适配
├── NestedTensorFactories.cpp # 工厂函数
└── cuda/ # CUDA 实现
嵌套张量(Nested Tensor)是 PyTorch 对变长序列批处理的原生支持,避免了 padding 带来的计算浪费。
10.4 native/quantized/ --- 量化
量化模块支持 INT8/INT4 推理,包括:
- 仿射量化器(AffineQuantizer)
- 伪量化(FakeQuantAffine)用于量化感知训练
- 量化卷积/线性层打包(通过 FBGEMM/QNNPACK)
- CUDA 量化内核(int4mm, int8mm)
10.5 functorch/ --- 函数变换的批处理规则
ATen/functorch/
├── BatchedTensorImpl.h/.cpp # 批处理张量实现
├── DynamicLayer.h/.cpp # 变换层栈管理
├── Interpreter.h/.cpp # 变换解释器
├── BatchRules*.cpp # ★ 各算子的 vmap 批处理规则(约 20 个文件)
│ ├── BatchRulesBinaryOps.cpp
│ ├── BatchRulesActivation.cpp
│ ├── BatchRulesLinearAlgebra.cpp
│ └── ...
├── TensorWrapper.h/.cpp # Tensor 包装器
└── VmapInterpreter.h/.cpp # vmap 解释器
当用户调用 torch.vmap(fn) 时,functorch 需要知道每个算子在增加一个批维度后应该如何行为------这就是 BatchRules*.cpp 中定义的规则。
十一、数据流全景:一次 torch.add() 的完整旅程
python
c = torch.add(a, b)
在 C++ 侧的完整调用路径:
1. at::add(a, b) // 生成的函数(ops/Functions.h)
│
▼
2. Dispatcher::call(aten::add.Tensor) // 分发器查找
│
├─ 检查 DispatchKey 优先级:
│ Autograd > FuncTorch > Backend
│
▼
3. AutogradCPU::add() // autograd 包装
│ 记录 grad_fn(AddBackward)到计算图
│
▼
4. CPU::add() (或 CUDA::add()) // 设备特化实现
│
▼
5. add_stub(kCPU, ...) // DispatchStub 选择指令集
│
├─ 如果 CPU 支持 AVX512 → add_kernel<AVX512>
├─ 如果 CPU 支持 AVX2 → add_kernel<AVX2>
└─ 否则 → add_kernel<DEFAULT>
│
▼
6. TensorIterator 构建 // 自动广播 + 类型提升
│
▼
7. cpu_kernel(iter, [](scalar_t a, scalar_t b) {
return a + b; // 最终的计算逻辑
});
│
▼
8. 内部并行化(OpenMP / 线程池)
+ Vectorized<float>::loadu → vadd → storeu
关键洞察 :用户写的一行 Python 代码,在 C++ 侧经过了分发器路由 → autograd 记录 → 设备/指令集选择 → 迭代器构建 → 向量化执行 至少 6 层抽象。
十二、文件规模与热点分布
基于目录遍历的粗略统计:
| 子目录 | 文件数(约) | 核心职责 |
|---|---|---|
native/ 顶层 |
~200 个 .cpp/.h | 算子公共实现 |
native/cuda/ |
~300 个 .cu/.cpp | CUDA 内核 |
native/cpu/ |
~90 个 .cpp | CPU 向量化内核 |
native/sparse/ |
~25 个 | 稀疏张量 |
native/quantized/ |
~20 个 | 量化 |
native/nested/ |
~15 个 | 嵌套张量 |
native/transformers/ |
~10 个 | 注意力机制 |
core/ |
~80 个 | 核心抽象 |
cuda/ |
~60 个 | CUDA 运行时 |
functorch/ |
~40 个 | vmap 批处理规则 |
顶层 ATen/*.h/*.cpp |
~100 个 | 公共 API 与基础设施 |
热点(改动最频繁的区域):
native/cuda/--- 性能优化的永恒战场native/transformers/--- LLM 时代的核心模块native_functions.yaml--- 每个新算子必经之路
十三、目录速查表
| 路径 | 一句话定位 |
|---|---|
native_functions.yaml |
上帝文件:所有算子的声明中心 |
native/*.cpp |
算子的通用 / CompositeImplicitAutograd 实现 |
native/cpu/*.cpp |
CPU 多指令集内核(AVX2/512/NEON) |
native/cuda/*.cu |
CUDA GPU 内核 |
native/mps/ |
Apple Metal 内核 |
native/mkldnn/ |
Intel oneDNN 加速 |
native/cudnn/ |
cuDNN 封装(卷积/BN/RNN) |
native/sparse/ |
稀疏张量操作 |
native/nested/ |
嵌套张量(变长批处理) |
native/transformers/ |
FlashAttention 等注意力实现 |
native/quantized/ |
INT8/INT4 量化算子 |
TensorIterator.h |
逐元素操作的统一迭代框架 |
Dispatch.h |
AT_DISPATCH 类型分发宏 |
native/DispatchStub.h |
CPU 指令集运行时分发 |
cpu/vec/ |
SIMD 向量化抽象库 |
core/ |
移动端友好的最小内核 |
cuda/ |
CUDA 运行时(cuBLAS/Context/Graph) |
detail/ |
设备钩子接口(插件式后端) |
functorch/ |
vmap/grad 批处理规则 |
templates/ |
代码生成模板 |
ops/ |
生成的 C++ 算子绑定 |
十四、阅读建议
如果你想添加新算子
- 先读
native/README.md(本文第四节的源文件) - 在
native_functions.yaml中添加声明 - 在
native/下编写 CompositeImplicitAutograd 实现 - 如需 CUDA 特化,在
native/cuda/添加.cu文件 - 在
tools/autograd/derivatives.yaml添加梯度公式
如果你想理解性能瓶颈
TensorIterator.h--- 理解广播和并行策略cpu/vec/--- 理解 SIMD 向量化cuda/CUDABlas.cpp--- 理解 GEMM 调用链native/cuda/Reduce.cuh--- 理解 GPU 归约模式
如果你想支持新硬件后端
detail/*HooksInterface.h--- 实现设备钩子native/DispatchStub.h--- 注册新设备的 stubnative_functions.yaml--- 添加新的 dispatch key
总结
ATen 是 PyTorch 的 C++ 算子引擎,其架构可以用三层来理解:
- 声明层 :
native_functions.yaml统一声明所有算子的签名和分发策略。 - 基础设施层 :
TensorIterator(迭代)、DispatchStub(CPU 指令集分发)、AT_DISPATCH(类型分发)、cpu/vec(SIMD 向量化)构成了算子实现的四大支柱。 - 实现层 :
native/下按算子类别和设备后端组织的数百个 C++/CUDA 文件。
理解 ATen,你就掌握了 PyTorch 性能优化的"底牌"------因为不管编译器栈多么花哨(Dynamo、Inductor、Triton),最终的单算子执行路径仍然落在 ATen 的 C++ 内核上。