当前位置: 首页 > news >正文

Triton源码目录:打开Triton源码的正确姿势:从一头雾水到心里有数

你有没有过这种经历——听说Triton写GPU Kernel很香,兴冲冲git clone下来,然后打开文件夹就懵了:include/lib/Dialect/Conversion/……一堆目录扑面而来,根本不知道从哪下手。

反正我有。第一次看Triton源码的时候,光目录结构就研究了半天,最后硬着头皮一个个文件点开看,效率低得令人发指。

后来跟着刘灿老师的分享系统地梳理了一遍,才算把Triton的源码骨架理清楚。这篇文章就是我当时的学习笔记,希望能帮你少走点弯路。

本文基于 triton-lang/triton 仓库(https://github.com/triton-lang/triton),以 PPT 内容为主线整理。


先看全景:四大核心目录

打开Triton仓库,你最先需要关注的是这四个目录:

别被其他目录分散注意力,include/、lib/、python/、runtime/这四个才是主干。其中include/lib/又是理解编译流程的重中之重——它们承载了Triton基于MLIR构建的整个编译管线。


include 和 lib:MLIR世界的"C头文件"和"实现"

include/ 里有什么?

Triton在MLIR框架上定义了两个核心Dialect:

  • Triton Dialect:高层、设备无关的IR。你写的tt.loadtt.storett.dot最终都会落到这个Dialect里。
  • TritonGPU Dialect:GPU相关的抽象,引入了Layout概念(Blocked、MMA、Slice、Shared等),决定了数据在GPU线程和内存中的分布方式。

include/下面主要就是这两个Dialect的Op定义(TableGen .td文件)类型定义属性定义

lib/ 里有什么?

lib/include/的对应实现,包括:

子目录作用
lib/Dialect/Triton/Triton Dialect的IR实现 + 优化Pass
lib/Dialect/TritonGPU/TritonGPU Dialect的IR实现 + 大量优化Pass
lib/Conversion/Dialect之间的转换(降级)逻辑
lib/Target/最终代码生成(LLVM IR → PTX / ROCm)

简单粗暴地记:include定义"是什么",lib实现"怎么做"


Dialect 目录:Triton编译器的灵魂

理解Dialect是理解Triton源码的关键。Triton的编译流程本质上就是Dialect的逐级降级

Triton Dialect ──→ TritonGPU Dialect ──→ LLVM Dialect ──→ 机器码 (高层语义) (GPU映射) (通用IR) (PTX/ROCm)

为什么要分两个Dialect?这是MLIR框架的精髓——分层抽象

  1. Triton Dialect完全不关心GPU硬件细节,只描述"做什么计算"(load、store、dot、reduce……)
  2. TritonGPU Dialect负责把计算映射到具体的GPU执行单元上——数据怎么分配到warp、怎么用Tensor Core、shared memory怎么管理

这种设计让前端(Python DSL)和后端(各种GPU)可以独立演进,互不干扰。


编译流程对应源码位置:一张图搞定

这是整份PPT里信息密度最高的一页:

把Triton的编译流程和源码目录对应起来,就长这样:

编译阶段源码位置做了什么
Triton IRlib/Dialect/Triton/定义高层Op语义,执行通用优化
Triton → TritonGPUlib/Conversion/TritonToTritonGPU/引入GPU Layout,分配warp
TritonGPU 优化lib/Dialect/TritonGPU/coalesce、pipeline、prefetch等大量GPU优化
TritonGPU → LLVMlib/Conversion/TritonGPUToLLVM/MMA lowering、shared memory处理
LLVM → 目标代码lib/Target/LLVMIR/生成LLVM IR,后面交给LLVM后端生成PTX

如果你想跟踪一个triton.dot操作从Python一路变成PTX指令的全过程,顺着这个表找对应文件就行。


常用文件速查手册

Triton Dialect 核心文件

Op定义/include/triton/Dialect/Triton/IR/TritonOps.td

这里定义了你在Python里调用的所有基础操作:

  • tt.calltt.functt.return—— 函数调用机制
  • tt.loadtt.store—— 全局内存读写
  • tt.dot—— 矩阵乘法,Triton的招牌操作

优化Pass/lib/Dialect/Triton/Transforms/

包含CombineOpsPassReorderBroadcastPassRewriteTensorPointerPassLoopUnrollPass等。这些Pass在GPU无关的层面做图优化——算子融合、死代码消除、循环展开,跟传统编译器优化的套路差不多。

Triton → TritonGPU 转换lib/Conversion/TritonToTritonGPU/TritonToTritonGPUPass.cpp

这是整个编译流程的第一个"硬核跳变"。在这里,设备无关的Triton IR被注入GPU-specific的Layout信息——数据开始被分配到具体的线程和内存层级。

TritonGPU Dialect 核心文件

Op定义/include/triton/Dialect/TritonGPU/IR/TritonGPUOps.td

GPU特有的操作:async_waitalloc_tensorinsert_slice_asyncconvert_layout

Layout属性定义/include/triton/Dialect/TritonGPU/IR/TritonGPUAttrDefs.td

这是TritonGPU最核心的设计——五种Layout:

Layout含义
Blocked数据按块分配给线程,最通用
MMA为Tensor Core矩阵乘累加定制
DotOperanddot操作的输入数据布局
Slice数据切片后的布局
Sharedshared memory中的数据布局

优化Pass/lib/Dialect/TritonGPU/Transforms/

这里有一大堆GPU专用Pass,每个都值得单独写一篇文章:

  • AccelerateMatmul—— 把普通矩阵乘匹配到Tensor Core指令
  • Pipeline/Prefetch—— 指令流水线和数据预取,Triton性能的核心来源
  • Coalesce—— 合并内存访问,减少bank conflict
  • RemoveLayoutConversions—— 消除不必要的layout转换开销
  • OptimizeThreadLocality—— 优化线程局部性
  • AllocateSharedMemoryPass—— shared memory分配

补充说明:PipelinePrefetch是Triton自动生成异步拷贝流水线的关键实现。它们会在循环内插入cp_async指令,让数据搬运和计算重叠执行——这正是Triton Kernel经常能追平甚至超过手写CUDA的原因。


一句话总结

Triton的源码结构本质上就是一条MLIR编译管线

include/ (定义) → lib/Dialect/ (IR实现) → lib/Conversion/ (Dialect降级) → lib/Target/ (代码生成)

如果你也想入手Triton源码,我的建议是:

  1. 先看include/triton/Dialect/Triton/IR/TritonOps.td,搞清楚Triton有哪些基础操作
  2. 跟踪triton.dot从 Triton Dialect → TritonGPU → LLVM 的完整降级路径
  3. mlir-opt --print-ir-before-all实际跑一遍 Pass Pipeline,直观感受每个Pass的效果

源码链接:https://github.com/triton-lang/triton


本文内容整理自先进编译实验室刘灿的分享,感谢。

http://www.jsqmd.com/news/1126837/

相关文章:

  • 终极指南:如何在Blender中直接导入Rhino 3D文件
  • ViGEmBus:Windows内核级游戏控制器虚拟化架构设计与实现
  • Seraphine:基于LCU API的英雄联盟自动化数据集成平台技术解析
  • MP8859与PIC18F4455实现高精度DC-DC降压电源设计
  • TPS65263与PIC18F26K40的嵌入式电源管理方案设计
  • 国家护网(HW)面试题汇总(最简版)
  • 从零掌握AI Agent Skill:原理、实战与自定义开发全指南
  • YOLOv5 + DeepSORT 实战:RTX 3060 实现 25 FPS 实时多目标跟踪
  • 设计模式——建造者器模式
  • 基于74HC32与PIC18F47Q10的矩阵键盘扩展方案
  • Grok 4 91.20 分登顶 WDCD 守约榜,Qwen3 Max 57.48 分垫底拉开 33.72 分差距
  • STM32H750XB与DC-DC降压电源转换方案设计
  • TPS65263与PIC18F85J10构建高效三重降压电源系统
  • 终极指南:如何在Blender中快速导入Rhino 3D文件实现无缝跨平台协作
  • 解锁Windows远程桌面功能:RDP Wrapper Library完全指南
  • MP8859与PIC18F67K40的数字电源控制方案解析
  • MP8859与PIC18F85J10的智能电源系统设计
  • Python xhs库终极指南:5分钟上手小红书数据采集完整教程
  • 智能装备集结武汉!2026国际汽车内外饰展会抢先看
  • WindowsCleaner终极指南:3分钟解决C盘爆红,免费提升系统性能50%
  • 突破Web界面限制:使用PowerCLI高效导出vSphere 6.7+ OVA模板
  • 嵌入式系统2x2键盘设计与PIC18F85K90实现
  • 工业传感器控制系统:AD74115H与STM32F334R8实战解析
  • DS28EC20与PIC18F57K42在嵌入式存储中的高效应用
  • eCognition 9.02 多尺度分割与地图同步:规避对象错位的3个关键参数设置
  • WindowsCleaner:开源系统优化工具解决Windows磁盘空间管理难题
  • PIC32与74HC32实现2x2键盘硬件消抖方案
  • 嵌入式系统电源管理:三重降压转换方案解析
  • PIC18LF4682与M95M04 EEPROM嵌入式存储方案详解
  • LENA-R8与dsPIC30F4011实现全球连接与精确定位