1 个稳定版本
1.0.0 | 2019年11月19日 |
---|
#2485 in 开发工具
145KB
4K SLoC
🚧 Geobacter Rust 编译器和运行时 🚧
什么是 Geobacter?
Geobacter 是一个支持单源加速器编程的框架,无需两次编译源代码。然而,Geobacter 并不是一个 JIT;预期内核会被反复调用,并且可能运行成本较高。事实上,由于单函数内核的性质,Geobacter 使许多对所有 crate 来说成本过高的 LLVM 选项变得可行。
Geobacter 的名字来源于第一种被发现可以使用氧化铁作为电子受体的细菌。
目前,AMDGPU 和 HPC 是重点。
这是如何工作的?
在 Rust 类型系统中,每个 fn
都有一个独特的类型。因此,我们可以通过类型来引用函数定义。在我们的 Rust 分支中,我们使用特殊的驱动定义的内嵌函数,实际上返回 Rust 编译器的 ty::Instance<'_>
形式,以及其他针对所需目标的具体信息(例如,支持 SPIR-V 管道描述)
在运行时,我们使用每个依赖项的元数据重新池化编译器驱动程序(进入运行时驱动程序)。然后我们查找真实的 DefId
,并通过一些编译器提供者 API 技巧,使 LLVM 代码生成 crate 为相应函数及其所有依赖项生成 IR。但要清楚的是,这并不是 JIT,并且不适合 JIT 类似的事物;例如,我们启用了额外的 LLVM 优化,如 Polly,并增加了优化搜索空间。因此,虽然优化相对较快,但对于 JIT 而言,它们太慢了。
有一个进程内缓存,以编译器生成的静态形式存在,因此内核不会在每个加速器目标上多次 codegen。
状态(即什么可行什么不可行)
通常情况下,直到 LLVM 优化为止的所有内容都适用于所有目标。在编译时为特定函数获取 ID 是可行的。在运行时,加载每个 crate 的元数据并使用它来设置伪 Rust 驱动程序是可行的,同样,运行上述函数 ID 并对其进行代码生成(包括优化)以及在(如果适用)将其发送到目标机器第二次也是可行的。
AMDGPU
此目标默认情况下即可工作,但调度需要一些不安全操作,因为仍然存在一些未解决的陷阱,例如将设备不可访问的内存(如栈)的引用传递给内核。此外,内核的输出必须显式通过指针传递,因为 &mut
必须是唯一的,但所有工作项共享相同的参数值!
"额外"功能
- 优雅的接口来指定内核启动范围,并高效地获取工作项/工作组的 ID,
- 设备可见的主机内存分配器,
- 设备内存分配,但这不能在
Box
/等中使用,因为无法保证大 BAR, - 设备纹理,
- 设备端信号,
- (大多数情况下)安全 LDS(工作组内存)接口适用于几个使用场景。
待办事项 🚧
- 更优雅的交叉条接口。
- 将 OpenCL std 函数适配到 Geobacter 等效。
- 安全输出写入:两个工作项不得创建对同一变量的可变引用。
- 设备端排队:需要机制将子内核图像句柄嵌入父内核。
- 设备 -> 主机 MPSC 通道。
Vulkan/SPIRV
Vulkan/SPIR-V 的支持远不如 AMDGPU,但“简单”的计算内核应该可以工作,目前还没有使用指南。
Geobacter 要求您的 Vulkan 实现支持物理存储缓冲区地址和变量指针扩展。
Cuda
无支持。
如何获取工具链?
目前,我们没有预构建的编译器可供您下载,更不用说直接从 rustup
下载的能力。
因此,您需要自己构建 Rust 工具链。请参阅 BUILD.md。
待办事项 🚧 提供预构建的软件包。
我该如何使用它进行编码?
请参阅 CODING.md! :^)
谁在从事这项工作?
Richard Diamond 在业余时间从事这项工作。
欢迎新贡献者。
依赖项
~0.6–1.3MB
~27K SLoC