1 个不稳定版本
0.1.0 | 2019年11月20日 |
---|
#530 in 图形API
230KB
5.5K 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,
- 设备可见的主机内存分配器,
- 设备内存分配,但此功能不能用于
Box
等等,因为无法保证大型BAR, - 设备纹理,
- 设备端信号,
- (主要是)一些使用场景的LDS(workgroup内存)接口是安全的。
待办事项 🚧
- 更好的交叉开关接口。
- 将OpenCL标准函数适配到Geobacter等效函数。
- 安全输出写入:两个workitem不能创建对同一变量的可变引用。
- 设备端队列:需要机制将子内核图像句柄嵌入到父内核中。
- 设备 -> 主机 MPSC 通道。
Vulkan/SPIRV
Vulkan/SPIR-V的支持不如AMDGPU,但“简单”的计算内核应该可以工作,并且目前还没有使用指南。
Geobacter要求您的Vulkan实现支持物理存储缓冲区地址和变量指针扩展。
Cuda
不支持。
如何获取工具链?
目前,我们还没有提供供您下载的预构建编译器,更不用说直接从 rustup
下载的能力。
因此,您需要自己构建Rust工具链。请参阅 BUILD.md。
待办事项 🚧 提供预构建包。
如何使用它进行编码?
请参阅 CODING.md! :^)
谁在开发这个?
Richard Diamond在业余时间从事这项工作。
欢迎新的贡献者。
lib.rs
:
用于Vulkan加速器的crate。
依赖关系
~10–20MB
~289K SLoC