CUDA是NVIDIA最早推出的通用数学运算库。除了基本的数学运算之外,还提供了一些工具包:
cuBLAS:线性计算库。除了基本版的API之外,它还包括以下扩展:
NVBLAS:多GPU版的cuBLAS。
cuFFT:FFT计算库。
nvGRAPH:图计算库。(这里的图是数学图论中的图,和DL框架中的计算图是两回事。)
cuRAND:随机数生成库。
官方文档:
https://docs.nvidia.com/cuda/pdf/CURAND_Library.pdf
cuSPARSE;稀疏矩阵计算库。
cuSOLVER:解线性方程的计算库。包括解稠密方程的cuSolverDN、解稀疏方程的cuSolverSP和矩阵分解的cuSolverRF。
官方文档:
https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html
https://github.com/nvidia/cccl
CUDA Core Compute Libraries (CCCL)
https://cuda.godbolt.org/
nvcc online compiler
NVIDIA DALI是一个GPU加速的数据增强和图像加载库,为优化深度学习框架数据pipeline而设计,而其中的NVIDIA nvJPEG是用于JPEG解码的高性能GPU加速库。
代码:
https://github.com/NVIDIA/dali
Tensor Core是Nvidia GPU自Volta架构开始,专门为深度学习矩阵运算设计的计算单元。
CUTLASS:另一个线性计算库,专为Tensor Core设计。

类似的东西还有Arm的SME、Intel的AMX等。

CUTLASS主要基于以下指令:
在这个过程中,计算粒度从warp(32 thread)->warp group(4x32thread)->Single-Thread Orchestration。

Blackwell架构里的Tensor Memory(TMEM)是一块专门为第五代Tensor Core运算设计的片上SRAM,位于每个SM内部,容量256 KB,大小与SM的寄存器文件相当。用于存放MMA指令的输入矩阵A和输出矩阵D,替代寄存器保存累加器,极大的缓解了寄存器的压力。
warp指令:一条被warp内32个线程集体发射、在SIMD流水线上锁步(lock-step)执行的指令。只要warp里任意一条线程被阻塞(例如访存等待),整条warp指令就暂停,32线程一起等待——这就是SIMT的“掩码+锁步”执行模型。
标量指令:它的“发射许可”不再检查“当前warp的32线程是否都到达”,而是任意一条线程跑到这条指令时,就可以独自把一次矩阵运算请求丢给Tensor Core,然后继续往下走。其他线程即使因为分支divergence没跑到这里,也不会阻塞这次提交。
https://www.zhihu.com/question/10639310321
如何看待第5代Tensor Core?
CuTe,全称为”collection of C++ CUDA template abstractions for defining and operating on hierarchically multidimensional layouts of threads and data”,是一个处理嵌套layout的模板抽象的集合,其并不提供现成算子支持,而是给出数据结构,使得复杂的线性代数计算得以加速。
https://dingfen.github.io/2024/08/18/2024-8-18-cute/
深入CUTLASS之CuTe详解
https://zhuanlan.zhihu.com/p/699255051
cute TiledMMA
Linear Layouts: Robust Code Generation of Efficient Tensor Computation Using F2
这篇论文使用F2群上的计算,来寻找register->thread->warp并行模型下的最优数据layout。
https://mp.weixin.qq.com/s/PDFshzgcj_udaFu3aJr1tQ
该论文的中文版
pingpong就是N=2的multi-stage,所以这个问题等价于为什么在Ampere NStage=2不够了。
Warp-Specialization的优势是在计算访存流水上的调度更灵活,劣势是代码写起来更麻烦。直到Ampere它的优势都不足以让人忍受它的劣势,而Hopper上Warp-Specialization变成了一种必须要使用的技术。
https://www.zhihu.com/question/11261005710
为什么Hopper架构上warp-specialization比multi-stage要好?
参考:
https://mp.weixin.qq.com/s/pPjPLqgXZ8iCPS42vXJpuQ
NVIDIA Tensor Core深度学习核心解析
https://mp.weixin.qq.com/s/Qfbc2iQnXacOqOGIrpRQRw
Tensor Core究竟有多快?全面对比英伟达Tesla V100/P100的RNN加速能力
https://www.zhihu.com/question/451127498
英伟达GPU的tensor core和cuda core是什么区别?
https://developer.nvidia.com/blog/cutlass-linear-algebra-cuda/
CUTLASS: Fast Linear Algebra in CUDA C++
https://zhuanlan.zhihu.com/p/663092747
cute之MMA抽象
https://zhuanlan.zhihu.com/p/712451053
cutlass GEMM流水线——single-stage、pipelined、multi-stage
https://research.colfax-intl.com/cutlass-tutorial-wgmma-hopper/
CUTLASS Tutorial: Fast Matrix-Multiplication with WGMMA on NVIDIA® Hopper™ GPUs
https://zhuanlan.zhihu.com/p/1945136522455122713
NVIDIA TMA全面分析
https://www.aleksagordic.com/blog/matmul
Inside NVIDIA GPUs: Anatomy of high performance matmul kernels
https://zhuanlan.zhihu.com/p/1996740631024924636
Swizzle工作原理
https://www.zhihu.com/question/667972067
cuda的swizzle是怎么实现bank conflict free的?
https://zhuanlan.zhihu.com/p/2007020183127094121
Blackwell Gemm实现
https://zhuanlan.zhihu.com/p/2007758781354897660
CUTLASS 教程:Blackwell GEMM-使用线程块cluster
Tile based的编程,逐渐替代传统的SIMT编程,成为LLM时代的首选。

PTX (Parallel Thread Execution) 是NVIDIA GPU的伪指令集,之所以加个伪字,主要是因为这个指令集并不是真的硬件指令集,而仅仅是个抽象指令集。
该抽象指令集可以屏蔽不同架构显卡之间的指令差异。

nvvm ir->PTX->SASS->runtime/jit->片上调度。
官网:
https://docs.nvidia.com/cuda/parallel-thread-execution/index.html

gcc和llvm都有特定的pass可以生成PTX代码。
CICC(CUDA Integrated Compiler Command)是CUDA Toolkit中的一个编译器组件,它负责将CUDA代码编译成PTX代码。
cudafe++是CUDA编译过程中的一个组件,它的主要作用是将CUDA特有的C++扩展转换成标准C++结构。
ptxas:和gcc中的as类似,也是一个汇编器。ptxas的作用是将PTX代码编译成SASS(Streaming Assembler)代码。
nvrtc:Runtime Compilation Library,用于在程序运行阶段把CUDA C++源码(以字符串形式给出)即时编译成PTX或CUBIN,从而无需事先用nvcc离线编译即可加载并执行GPU内核。
官方文档:
https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html
NVIDIA GPU真正的指令集,被称作SASS。
和.ptx文件相对应,SASS的二进制格式为.cubin文件。但是由于后者是真正的硬件指令,在各架构之间不通用,所以还有一个.fatbin文件,可以打包不同架构的bin。
https://zhuanlan.zhihu.com/p/161624982
SASS指令集概述
https://www.zhihu.com/question/639210103
为什么没人去做CUDA逆向和反编译?
Thrust是一个C++库,它提供了对GPU加速并行算法的便捷访问。
它对标的是STL和TBB(Threading Building Blocks),后者是Intel开源的并行计算的C++模板库。
CUB是一个底层CUDA C++模板库,为CUDA开发者提供可组合、高性能的原语,提供了Scan、Sort、Reduce、Histogram等操作的模板。
Thrust的底层实际调用CUB进行优化。
从Ampere架构开始,引入了异步访存指令。
同步版本的流水线访存就是ld.global到registers,然后st.shared写入到共享内存,它们都会阻塞计算指令,但是warp scheduler会通过warp切换,让其他已经eligible的warp继续执行(本质上还是ILP),因此,一般同步版本最多开双流水(double-buffer),因为需要额外的寄存器进行prefetch,占用率不会太高,计算没法更好地掩盖访存的延迟。
异步版本是硬件层面的异步指令(cp/store.async),本身计算和访存单元就是可以独立运行的,有了异步层级的指令支持后,可以充分发挥这一特点,指令不会阻塞计算指令,但是需要fence/barrier等同步手段,因此,warp可以继续执行下去(如果条件允许),此外,这些指令需要消耗额外的寄存器进行预取,直接global->shared或者shared->global,一般可以开2-4条流水。
https://zhuanlan.zhihu.com/p/709750258
Tensor Memory Access(TMA)
Device to Device (DtoD):指的是在单个GPU内部进行的内存拷贝。
Peer to Peer (PtoP):指的是从一个GPU到另一个GPU的内存拷贝,这种情况仅发生在多GPU系统中。
RR (Read-Read):表示连续的读操作。
RW (Read-Write):表示读写混合操作。
Generic Addr是一种不携带任何状态或附加信息来声明它属于哪个状态空间的指针。在CUDA C++中,与C++一样,指针就是指针,它们没有额外的装饰或元信息。在PTX或SASS中,CUDA GPU具有状态空间系统,这是一种分区寻址结构。例如,shared就是一个状态空间。

您的打赏,是对我的鼓励