#geobacter #amd-gpu #run-time #kernel #devices #compiler #requires

nightly geobacter-runtime-amd

Geobacter AMDGPU特定运行时。需要Geobacter Rust编译器。

2个版本 (1个稳定版)

1.0.0 2019年11月20日
0.1.0 2019年11月20日

#2127 in 开发工具

MIT/Apache

480KB
13K SLoC

🚧 Geobacter Rust 编译器和运行时 🚧

什么是Geobacter?

Geobacter是一个支持单源加速器编程的框架,无需从源代码编译两次。然而,Geobacter不是一个即时编译器(JIT);预期是内核会被重复调用,并且运行可能很昂贵。实际上,由于单函数内核的特性,Geobacter启用了一些对于所有crate来说运行成本过高的LLVM选项。

Geobacter这个名字来源于最早发现的能够利用氧化铁作为电子受体的有机物氧化细菌。

目前,AMDGPU和高性能计算是主要关注的领域。

它是如何工作的?

在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 必须是唯一的,但所有工作项共享相同的参数值!

“额外”功能

  • 优雅的接口指定内核启动边界并高效地获取工作项/工作组ID,
  • 设备可见的主机内存分配器,
  • 设备内存分配,但此功能不能在 Box/等中使用,因为无法保证大BAR(Buffer Address Register),
  • 设备纹理,
  • 设备端信号,
  • (大多数情况下)安全的LDS(工作组内存)接口,适用于一些使用场景。

待办事项 🚧

  • 更友好的交叉栏接口。
  • 将OpenCL标准函数适配到Geobacter等效函数。
  • 安全的输出写入:两个工作项不能创建对同一变量的可变引用。
  • 设备端队列:需要机制将子内核图像句柄嵌入到父内核中。
  • 设备到主机MPSC通道。

Vulkan/SPIRV

Vulkan/SPIR-V的支持不如AMDGPU,但“简单”的计算内核应该可以工作,并且目前还没有使用指南。

Geobacter要求您的Vulkan实现支持物理存储缓冲区地址和变量指针扩展。

Cuda

不支持。

如何获取工具链?

目前,我们没有预构建的编译器供您下载,更不用说直接从 rustup 下载的能力。

因此,您需要自己构建Rust工具链。请参阅 BUILD.md。

待办事项 🚧 提供预构建包。

如何使用它进行编码?

请参阅 CODING.md! :^)

谁在开发这个?

Richard Diamond在业余时间从事这项工作。

新贡献者绝对欢迎。


lib.rs:

AMDGPU的运行时crate。

包括通过信号管理设备资源的WIP支持

待办事项:直接使用 hsaKmt API。HSA运行时进行了一些全局(!)锁定,我们可以避免因为Rust很棒。由于HSA几乎仅限于AMD,我们可以仅限于AMD并更直接地为其GPU编程。

依赖项

~5–17MB
~234K SLoC