1 个稳定版本
1.0.0 | 2019年11月19日 |
---|
#2525 在 开发工具 中
225KB
6K 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来说,速度还是太慢。
存在一个进程内缓存,形式为编译器生成的静态数据,因此内核不会在加速器目标上多次代码生成。
状态(即什么工作,什么不工作)
一般情况下,直到LLVM优化为止,所有目标都适用。在编译时为特定函数获取ID是可行的。在运行时,加载每个crate的元数据并使用这些数据来设置伪Rust驱动器是可行的,同时上述函数ID和运行代码生成(包括优化)也是可行的,如果适用的话,还可以将其发送到目标机器进行第二次运行。
AMDGPU
此目标可以直接使用,尽管调度需要一些不安全操作,因为仍然存在一些未解决的问题,例如将引用设备不可访问的内存(如栈)传递给内核。此外,内核输出必须显式通过指针传递,因为&mut
必须唯一,但所有workitems共享相同的参数值!
"额外"功能
- 提供良好的接口来指定内核启动边界并有效地获取workitem/workgroup ID,
- 设备可见的主机内存分配器,
- 设备内存分配,但由于无法保证大的BAR,因此不能在
Box
等中使用, - 设备纹理,
- 设备端信号,
- (主要)安全LDS(工作组内存)接口,适用于一些使用场景。
待办事项 🚧
- 更好的交叉条接口。
- 将OpenCL标准函数适配为Geobacter等效函数。
- 安全输出写入:两个workitem不能创建对同一变量的可变引用。
- 设备端排队:需要机制将子内核图像句柄嵌入到父内核中。
- 设备 -> 主机 MPSC 通道。
Vulkan/SPIRV
Vulkan/SPIR-V的支持不如AMDGPU,但“简单”计算内核应该可以工作,目前还没有其使用指南。
Geobacter要求你的Vulkan实现支持物理存储缓冲区地址和变量指针扩展。
Cuda
无支持。
如何获取工具链?
目前,我们没有预构建的编译器可供下载,更不用说直接从rustup
下载的能力。
因此,你需要自己构建Rust工具链。参见BUILD.md。
待办事项 🚧提供预构建包。
如何使用这个工具编写代码?
请参阅CODING.md! :^)
谁在开发这个项目?
Richard Diamond在业余时间从事这项工作。
新贡献者绝对欢迎。
依赖关系
~7MB
~137K SLoC