PyTorch 学习笔记(12):ATen C++ 算子引擎的完整架构之旅

一、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):

  1. native/cpu/ 中的所有实现必须放在匿名命名空间中,否则不同指令集版本的符号会在链接时冲突。
  2. 只有需要利用 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 内核通常使用以下模式之一:

  1. TensorIterator + gpu_kernel:用于逐元素操作,自动处理广播和类型提升。
  2. 手写 CUDA kernel:用于无法用 TensorIterator 表达的复杂操作(如 sort、scatter)。
  3. 调用外部库: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/64
  • AT_DISPATCH_FLOATING_TYPES --- float/double
  • AT_DISPATCH_ALL_TYPES_AND(kHalf, ...) --- 增加 float16
  • AT_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 与基础设施

热点(改动最频繁的区域):

  1. native/cuda/ --- 性能优化的永恒战场
  2. native/transformers/ --- LLM 时代的核心模块
  3. 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++ 算子绑定

十四、阅读建议

如果你想添加新算子

  1. 先读 native/README.md(本文第四节的源文件)
  2. native_functions.yaml 中添加声明
  3. native/ 下编写 CompositeImplicitAutograd 实现
  4. 如需 CUDA 特化,在 native/cuda/ 添加 .cu 文件
  5. tools/autograd/derivatives.yaml 添加梯度公式

如果你想理解性能瓶颈

  1. TensorIterator.h --- 理解广播和并行策略
  2. cpu/vec/ --- 理解 SIMD 向量化
  3. cuda/CUDABlas.cpp --- 理解 GEMM 调用链
  4. native/cuda/Reduce.cuh --- 理解 GPU 归约模式

如果你想支持新硬件后端

  1. detail/*HooksInterface.h --- 实现设备钩子
  2. native/DispatchStub.h --- 注册新设备的 stub
  3. native_functions.yaml --- 添加新的 dispatch key

总结

ATen 是 PyTorch 的 C++ 算子引擎,其架构可以用三层来理解:

  1. 声明层native_functions.yaml 统一声明所有算子的签名和分发策略。
  2. 基础设施层TensorIterator(迭代)、DispatchStub(CPU 指令集分发)、AT_DISPATCH(类型分发)、cpu/vec(SIMD 向量化)构成了算子实现的四大支柱。
  3. 实现层native/ 下按算子类别和设备后端组织的数百个 C++/CUDA 文件。

理解 ATen,你就掌握了 PyTorch 性能优化的"底牌"------因为不管编译器栈多么花哨(Dynamo、Inductor、Triton),最终的单算子执行路径仍然落在 ATen 的 C++ 内核上。

相关推荐
旖-旎2 小时前
链表(两两交换链表中的节点)(2)
数据结构·c++·学习·算法·链表·力控
landuochong2002 小时前
用 Claude Code 直接写 Obsidian 笔记-增强版
人工智能·笔记·skill·claudecode
知识分享小能手2 小时前
MongoDB入门学习教程,从入门到精通,MongoDB的分片管理(17)
数据库·学习·mongodb
世人万千丶2 小时前
Flutter 框架跨平台鸿蒙开发 - 嫉妒分析器应用
学习·flutter·华为·开源·harmonyos·鸿蒙
泰晶科技2 小时前
【晶振电子元件基本术语】
笔记
IT摆渡者2 小时前
JUMPSERVER堡垒机部署
linux·运维·网络·经验分享·笔记
AI_零食2 小时前
Flutter 框架跨平台鸿蒙开发 - 社交断舍离应用
运维·服务器·学习·flutter·游戏·开源·harmonyos
fengci.3 小时前
php反序列化(复习)(第二章)
android·开发语言·学习·php