Rust in Everything
基于 tenferro-runtime 0.8.0

GPU 与 XLA

前几部分的张量都在主机内存里,engine 是 CpuEngine。这一部分讲另外两个终点:tenferro-gpu 的 CudaEngine,它和 CpuEngine 实现同一套 Engine trait,张量要先显式上传;以及 tenferro-xla,它不是 engine,而是把整段 traced 程序翻成 StableHLO 交给外部的 XLA 编译器。

本机没有 NVIDIA GPU、没有 CUDA 驱动,也没有 PJRT 插件;WebGPU 后端在 0.8.0 已经删掉。所以这一部分的两页都只读源码,没有在 GPU 上跑过任何东西。 跑过的只有不碰设备的部分:离线编译、没有驱动或插件时各入口怎么失败、能力表、内核目录生成的源码、StableHLO lowering。

0.8.0 里 GPU 只有 CUDA。0.7.1 的 tenferro-gpu 有两个后端,都建在 tensor4all 的 CubeCL 分叉上:CUDA 和 WebGPU(macOS 上经 wgpu 走 Metal)。#2291 把 CUDA 换成了 kernel-catalogue engine,同一个 PR 里的提交 d8ddd68d 写明「the CubeCL engine, its kernels and the WebGPU/Metal lane are gone」;之后的 CI 提交 cb04814d 的说法是「The WebGPU/Metal lane retired with the CUDA cutover (#2208)」。提交说明里没有单独讲 WebGPU 为什么不保留,能查到的是两条背景。一是 WebGPU 路线本来就卡在分叉上:tag 上还留着的 cubecl-011-webgpu-state.md 记录了迁到 CubeCL 0.11 时剩下的 7 处编译错误,都是 Apple / Metal 主机可见内存要用的接口,「Upstream 0.11 has none of them」,只有 tensor4all 自己的移植版有。二是新的内核目录是 CUDA C++ 源码,不再有一份能同时编到 CUDA 和 WebGPU 的内核语言;t4a-gpu-backend 的 README(cargo 缓存里的 t4a-cuda-runtime 0.1.0)写的是「HIP/ROCm, Metal and Intel GPU implementations are future directions. Each can use its native execution model」,gpu/mod.rs 的模块注释也把以后的第二个后端排成「(ROCm/HIP, then Metal)」。

文档没有跟上。README 的介绍段落仍写着直接 API「run through a chosen CPU, CUDA, or experimental WebGPU backend」,crate 表里 tenferro-gpu 一行是「CUDA backend support, experimental WebGPU support, future ROCm substrate」(README 的其余出入见 tenferro 解决什么问题)。用户指南 devices-and-gpu.md 的 provider 表还有「WebGPU | Experimental | webgpu」一行,还有一节「WebGPU Quickstart」教人写 features = ["webgpu"];tenferro-xla 的 crate 文档也还在说「CUDA, or WebGPU execution」。照着指南写,cargo 在解析依赖时就停下:「tenferro-gpu does not have that feature」。

  1. CUDA(只读源码):CudaEngine 是一个 t4a-cuda-runtime 运行时加一套缓存,内核来自 t4a-cuda-kernels 的内核目录(58 个入口、11 个 CUDA C++ 编译单元),NVRTC 按模块编译,TENFERRO_CUDA_ARTIFACT_CACHE 把编译产物落盘;dot_general 走 cuTENSOR,线性代数和 FFT 走 cuSOLVER、cuFFT,缺库报类型化错误;每个直接运算返回前都同步,融合没接上;没有驱动时 cuda_devices() 仍在 cudarc 里 panic。
  2. XLA(只读源码):tenferro-xla 把 CompiledGraph 拼成 StableHLO 文本,只收精确静态形状、F32 / F64 和 23 个核心算子,没有 Sub,0.8.0 的组合运算里只有 gelu_tanh 翻得过去;PJRT 插件运行期加载,每次执行都重新建客户端、重新编译。
flowchart TB
  eng["Engine trait"] --> cpu["CpuEngine"]
  eng --> cuda["CudaEngine"]
  cuda --> t4r["t4a-cuda-runtime"]
  cuda --> cat["t4a-cuda-kernels"]
  cuda --> libs["cuTENSOR 等"]
  prog["CompiledGraph"] --> rt["Runtime"]
  rt --> eng
  prog --> xla["tenferro-xla"]
  xla --> pjrt["PJRT 插件"]

和 burn、candle 对照:burn 的整个张量 API 都能落到 CubeCL 上(见 06 CubeCL 与 GPU),candle 的 Metal 后端直接调 Metal(见 Metal 后端)。tenferro 0.8.0 走的是第三条路:只做 CUDA,内核是 CUDA C++ 源码,运行期用 NVRTC 编译,取舍的讨论在 08 设计取舍。

💬 关联讨论

发起讨论
加载中...