Zaneham/BarraCUDA

GitHub: Zaneham/BarraCUDA

一个从零用 C99 编写的开源 CUDA C++ 编译器,解决跨 AMD、NVIDIA 与 Tenstorrent 多 GPU 架构的编译与性能可控问题。

Stars: 1626 | Forks: 77

# BarraCUDA 一个从零开始用 C99 编写的开源 CUDA C++ 编译器,它接收 `.cu` 文件并将其编译为 AMD GPU 机器码、NVIDIA PTX 和 Tenstorrent Tensix C++,计划支持更多架构。不依赖 LLVM,无依赖,无需许可。 当你审视 NVIDIA 的封闭生态并想“这能有多难?”时,这就是会发生的一切。答案是:其实挺难,但我还是做到了。 查看 [更新日志](#changelog) 了解最新动态。 ## 功能 将 CUDA C 源代码(与传给 `nvcc` 的 `.cu` 文件相同)编译为 AMD RDNA 2/3/4 二进制文件、NVIDIA PTX 或 Tenstorrent Tensix Metalium C++。 ``` ┌───────────────────────────────────────────────────────────────────────────┐ │ BarraCUDA Pipeline │ ├───────────────────────────────────────────────────────────────────────────┤ │ Source (.cu) │ │ ↓ │ │ Preprocessor → #include, #define, macros, conditionals │ │ ↓ │ │ Lexer → Tokens │ │ ↓ │ │ Parser (Recursive Descent) → AST │ │ ↓ │ │ Semantic Analysis → Type checking, scope resolution │ │ ↓ │ │ BIR (BarraCUDA IR) → SSA form, typed instructions │ │ ↓ │ │ mem2reg → Promotes allocas to SSA registers │ │ ↓ │ │ Instruction Selection │ │ ├──────────────────┬──────────────────┬────────────────────┤ │ │ ↓ AMD ↓ NVIDIA ↓ Tenstorrent │ │ │ VGPR/SGPR regalloc PTX isel + emit Tensix SFPU isel │ │ │ ↓ ↓ ↓ │ │ │ GFX9/10/11/12 .ptx text Metalium C++ │ │ │ binary encoding (driver JIT) compute/reader/writer │ │ │ ↓ ↓ ↓ │ │ │ .hsaco ELF Runs on NVIDIA Runs on Tenstorrent │ │ │ ↓ hardware hardware │ │ │ Runs on AMD │ │ │ hardware │ │ └───────────────────────────────────────────────────────────────────────────┘ ``` ## 构建 ``` # 它是 C99。它使用 gcc 构建。没有依赖项。 make # 仅此而已。没有 cmake。没有 autoconf。没有 47 步构建过程。 # 如果这不起作用,是你的 gcc 坏了,而不是 Makefile。 ``` ### 要求 - 一个 C99 编译器(gcc、clang 或你已有的任何) - 求生的意志(可选但推荐) - 不需要 LLVM。BarraCUDA 像成年人一样自行完成指令编码。 ## 使用 ``` # 编译为 AMD GPU 二进制文件(RDNA 3,默认) ./barracuda --amdgpu-bin kernel.cu -o kernel.hsaco # 编译为 RDNA 2 ./barracuda --amdgpu-bin --gfx1030 kernel.cu -o kernel.hsaco # 编译为 RDNA 4 ./barracuda --amdgpu-bin --gfx1200 kernel.cu -o kernel.hsaco # 编译为 NVIDIA PTX ./barracuda --nvidia-ptx kernel.cu -o kernel.ptx # 编译为 Tenstorrent Metalium C++ ./barracuda --tensix kernel.cu -o kernel_compute.cpp # 转储 IR(用于调试或好奇) ./barracuda --ir kernel.cu # 仅解析并转储 AST ./barracuda --ast kernel.cu # 运行语义分析 ./barracuda --sema kernel.cu # 使用毛利语(或任何带有翻译文件的语言)的错误信息 ./barracuda --lang lang/mi.txt --amdgpu-bin kernel.cu -o kernel.hsaco ``` ## 运行时启动器 BarraCUDA 包含一个极简的 HSA 运行时(`src/runtime/`),用于在真实 AMD 硬件上分发已编译的内核。零编译时依赖 ROCm —— 通过 `dlopen` 在运行时加载 `libhsa-runtime64.so`。 ``` # 同时编译运行时和示例 gcc -std=c99 -O2 -I src/runtime \ examples/launch_saxpy.c src/runtime/bc_runtime.c \ -ldl -lm -o launch_saxpy # 编译一个内核并运行它 ./barracuda --amdgpu-bin -o test.hsaco tests/canonical.cu ./launch_saxpy test.hsaco ``` 需要安装 ROCm 的 Linux 系统。完整的示例请参见 `examples/launch_saxpy.c`。 ## 支持的功能 以下 CUDA 特性可编译为可用的 GFX9/GFX10/GFX11/GFX12 机器码、NVIDIA PTX 和 Tensix Metalium C++: ### 核心语言 - `__global__`、`__device__`、`__host__` 函数限定符 - `threadIdx`、`blockIdx`、`blockDim`、`gridDim` 内置变量 - 结构体(命名与匿名内联)、枚举、类型定义、命名空间 - 指针、数组、指针运算 - 全部 C 控制流:`if`/`else`、`for`、`while`、`do-while`、`switch`/`case`、`goto`/`label` - 短路求值的 `&&` 和 `||` - 条件运算符 - 模板(基础实例化) - 多返回路径、`continue`、`break` ### CUDA 特性 - `__shared__` 内存(从 LDS 分配并正确跟踪) - `__syncthreads()` → `s_barrier` - 原子操作:`atomicAdd`、`atomicSub`、`atomicMin`、`atomicMax`、`atomicExch`、`atomicCAS`、`atomicAnd`、`atomicOr`、`atomicXor` - 战争期原语:`__shfl_sync`、`__shfl_up_sync`、`__shfl_down_sync`、`__shfl_xor_sync` - 战争期投票:`__ballot_sync`、`__any_sync`、`__all_sync` - 向量类型:`float2`、`float3`、`float4`、`int2`、`int3`、`int4`,支持 `.x`/`.y`/`.z`/`.w` 访问 - 半精度:`__half`、`__float2half()`、`__half2float()`、`__nv_bfloat16` - `__launch_bounds__`(解析、传递并强制 VGPR 上限) - 协同程序组:`cooperative_groups::this_thread_block()`,支持 `.sync()`、`.thread_rank()`、`.size()` - 运算符重载 - 数学内置函数:`sqrtf`、`rsqrtf`、`expf`、`exp2f`、`logf`、`log2f`、`log10f`、`sinf`、`cosf`、`tanf`、`tanhf`、`powf`、`fabsf`、`floorf`、`ceilf`、`truncf`、`roundf`、`rintf`、`fmaxf`、`fminf`、`fmodf`、`copysignf` - `__constant__` 内存、`__device__` 全局变量 ### 编译器特性 - 完整的 C 预处理器:`#include`、`#define`/`#undef`、函数式宏、`#ifdef`/`#ifndef`/`#if`/`#elif`/`#else`/`#endif`、`#pragma`、`#error`、`-I`/`-D` 参数 - 错误恢复(报告多个错误而不会挂起) - 多语言错误消息(`--lang <文件>`)与语言中立的 E 码 - IR 转储中的源码位置跟踪 - 按值传递结构体 ## 示例 ``` __global__ void vector_add(float *c, float *a, float *b, int n) { int idx = threadIdx.x + blockIdx.x * blockDim.x; if (idx < n) c[idx] = a[idx] + b[idx]; } ``` ``` $ ./barracuda --amdgpu-bin vector_add.cu -o vector_add.hsaco wrote vector_add.hsaco (528 bytes code, 1 kernels) ``` 无需 LLVM ✅ ## 验证过的硬件 BarraCUDA 编译的内核已在真实硅片上验证并产生正确结果: - **AMD MI300X(CDNA3,GFX942)** — 8/8 测试内核通过。蒙特卡洛中子输运产生正确的物理结果(k_eff = 0.995,与参考一致)。 - **AMD RDNA3(GFX1100)** — 通过 RDNA3 模拟器 CI 的完整测试套件。 - **NVIDIA RTX 4060 Ti** — PTX 后端,通过 CUDA Driver API 加载,由 NVIDIA 驱动 JIT 编译。蒙特卡洛中子输运基准测试产生正确结果,相比单线程 CPU 提速 3.8 倍。流程中完全不涉及 NVCC。 - **Tenstorrent Blackhole** — 编译为有效的 Metalium C++。硬件验证待开发套件接入。 ## 尚未支持的功能(目前) 诚实地说明限制很重要。以下是当前缺失的功能: - `__device__` 函数中的参数重新赋值(改用局部变量) - 纹理与表面 - 动态并行化(设备端内核启动) - 多翻译单元 - 主机代码生成(仅编译设备代码) 这些都不是架构障碍,只是“尚未实现”的项目。 ## 测试套件 14 个测试文件,35+ 个内核,约 1,700 条 BIR 指令,约 27,000 字节机器码: - `vector_add.cu` — GPU 计算的“Hello World” - `cuda_features.cu` — 原子操作、战争期原语、屏障、goto、switch、短路 - `test_tier12.cu` — 向量、共享内存、运算符重载 - `notgpt.cu` — AI 生成的 CUDA 代码,包含极富讽刺意味的注释(平铺 SGEMM、规约、直方图、前缀扫描、模板、半精度、协同程序组及“万能”内核) - `stress.cu` — N 体模拟、嵌套控制流、位操作、按值传递结构体、链式函数调用 - `canonical.cu` — 来自 NVIDIA 示例并适配解析器的规范模式 - `test_errors.cu` — 故意编写的语法错误以验证错误恢复 - `test_launch_bounds.cu` — `__launch_bounds__` 解析与 VGPR 上限强制 - `test_coop_groups.cu` — 协同程序组降级 - `mymathhomework.cu` — 三角恒等式、指数增长、牛顿-拉夫森、对数定律、双曲函数、向上/向下取整/取整、幂律、限幅 - 还包括预处理器测试、模板测试、无符号整数测试 ## 路线图 ### 近期:强化 修复已知缺口:整数字面量后缀、`const`、参数重新赋值。这些都是小型解析器/降级器的变更。目标是无需修改即可编译真实的 `.cu` 文件。 ### 中期:优化 生成的代码可用但尚未赢得任何基准。目前已完成:指令调度、常量折叠、死代码消除、基于分歧的 SSA 寄存器分配。优先级: - 循环不变代码外提 - 基于寄存器压力的占用率调优 ### 长期:更多架构 IR(BIR)是目标无关的,后端清晰分离。添加新目标编写新的 `isel` + `emit` 对。 - **NVIDIA PTX** — 已完成。编译 CUDA 为 PTX 文本,通过 CUDA Driver API 加载并由 NVIDIA 驱动 JIT 编译。参数:`--nvidia-ptx` - **Tenstorrent Tensix** — 已完成。编译 CUDA 为 TT-Metalium C++ 以用于 Blackhole。参数:`--tensix` - **Intel Arc** — Xe 架构。若能覆盖所有四大 GPU 厂商,BarraCUDA 将更完整。 - **RISC-V 向量扩展** — 当 GPU 过于主流而你希望在软核上运行 CUDA 时。 ## 贡献 **任何语言的问题与 PR 都欢迎** —— 只需附带英文翻译即可。完整风格、命名及协助指南请参见 [CONTRIBUTING.md](CONTRIBUTING.md)。 HLASM 风格的短标识符(`ra_gc`、`mk_hash`、`enc_vop3`)偶然具有文化中立性,5 个字符的标签并无“英文”属性。如果你发现漏洞或有想法,请用你习惯的语言写下它。 ## 更新日志 **2026-03-18** — NVIDIA PTX 后端(`--nvidia-ptx`)。将 CUDA 编译为 PTX 文本,通过 CUDA Driver API 加载并由 NVIDIA 驱动 JIT 编译。验证于运行蒙特卡洛中子输运基准的 RTX 4060 Ti,物理结果正确。无需 NVCC。还包括解析器、语义分析器和降级器中的匿名结构体/联合体支持(`struct { float f; int i; } cvt;` 模式)。 **2026-03-14** — 发散感知 SSA 寄存器分配器(`--ssa-ra`)。在一个 654 行的蒙特卡洛传输内核中消除全部 186 个 VGPR 溢出——临时流量减少 78%,总指令数减少 28%。利用了 Wave64 硬件上发散与统一 VGPR 溢出的 64:1 成本不对称性:统一值通过 `v_readfirstlane` 以每项 4 字节溢出,而发散值保留在寄存器中。灵感来自 Sampaio 等(2013)的发散分析。约 1,300 行 C99 代码,全部静态内存,无 malloc。 **2026-03-09** — 后 isel 验证通过(`bc_vfy`)。编码器曾信任 isel 生成有效机器指令,这并不正确。`bc_vfy` 在两次运行中(后 isel、后 RA)捕获 5 类编码违规,防止二进制文件离开编译器。其首次运行立即发现了 7 个 isel 错误,覆盖 GFX10 与 GFX942 —— 每个都是静默错误编译,会在硬件上触发“未知原因”故障。全数修复。还新增了 `bc_abend` 运行时崩溃诊断,因为若 IBM 能在 1964 年做事后转储,我们也能在 2026 年为 GPU 做此事。 **2026-03-08** — 错误定位基础设施。每个诊断现在拥有语言中立的 ID(`E001`–`E111`)。通过 `--lang <文件>` 提供外部翻译文件。英文参考位于 `lang/en.txt`,毛利语位于 `lang/mi.txt`。统一错误结构体。降级错误现已显示。 **2026-03-05** — CDNA 3 新增功能:GFX942 后端强化、MFMA、Wave64 发散、tinygrad 兼容。MI300X 上 8/8 测试通过([PR#56](https://github.com/Zaneham/BarraCUDA/pull/56))。 **2026-03-05** — 指令调度([PR#52](https://github.com/Zaneham/BarraCUDA/pull/52))。 **2026-03-03** — CDNA 2 支持(`--gfx90a`,MI250)。tinygrad 兼容。 **2026-02-28** — Tenstorrent Tensix 后端(`--tensix`)。编译 CUDA 为 TT-Metalium C++ 以用于 Blackhole。常量折叠([PR#51](https://github.com/Zaneham/BarraCUDA/pull/51))。死代码消除([PR#48](https://github.com/Zaneham/BarraCUDA/pull/48))。 **2026-02-25** — HSA 运行时启动器([PR#40](https://github.com/Zaneham/BarraCUDA/pull/40))。RDNA 2 支持(`--gfx1030`,[PR#38](https://github.com/Zaneham/BarraCUDA/pull/38))。测试套件([PR#41](https://github.com/Zaneham/BarraCUDA/pull/41))。 **2026-02-20** — RDNA 4 支持(`--gfx1200`,[PR#32](https://github.com/Zaneham/BarraCUDA/pull/32))。 **2026-02-16** — 初始发布。面向 AMD RDNA 3(gfx1100)的 CUDA 编译器。 ## 联系 发现漏洞?想讨论 AMDGPU 指令编码的细节?需要有人一起吐槽 GPU 计算现状? **zanehambly@gmail.com** 如有任何问题,欢迎创建议题。或者不。我不是你妈。 位于新西兰,那里已经快到了,而 GPU 和其他地方一样困惑。 ## 许可证 Apache 2.0。随意使用。如果这个编译器 somehow 被用于生产环境,我很乐意听到,主要是为了能在 LinkedIn 上更新比“写了一个 CUDA 编译器当乐子”更有趣的内容。 ## 致谢 - **Fernando Magno Quintão Pereira** 与 **UFMG 的编译原理实验室**(Universidade Federal de Minas Gerais)。Fernando 在看到项目后联系了我,向我介绍了分歧分析论文并提供指导。SSA 寄存器分配器的存在源于那次对话。 - **学术界** — Cooper、Harvey 与 Kennedy 提供了支配树;Braun 与 Hack 提供了 SSA 溢出;Sampaio、Souza、Collange 与 Pereira 提供了分歧分析。我只是个读论文写 C 的业余爱好者。真正艰苦的工作由研究人员完成。 - **Steven Muchnick** 的《Advanced Compiler Design and Implementation》。如果这个编译器做对了一些事,都要归功于这本书。 - **Low Level** 的《Zero to Hero C》课程和 YouTube 频道。我在那里学会了 C。 - **Abe Kornelis**,一位极棒的老师。他在 [z390 Portable Mainframe Assembler](https://github.com/z390development/z390) 项目上的工作值得你花时间。 - 感谢所有发送善意与批评信息的人,感谢你们永远的学生与快乐的业余爱好者。 - 我的奶奶、爷爷、奶奶与 Baka。爱你们 x *He aha te mea nui o te ao. He tāngata, he tāngata, he tāngata.* 世界上最重要的事物是什么?是人,是人,是人。
标签:AMD GPU, C99, CUDA, GPU, GPU 编译, Hakrawler, NVIDIA PTX, RDNA, Tensix, Tenstorrent, Vectored Exception Handling, 图形编程, 客户端加密, 并行计算, 开源, 异构计算, 技术挑战, 无依赖, 源码编译, 编译器, 自研, 跨架构, 高性能计算