用Go开发无cgo的CUDA绑定用于ML任务——第三周——开源 [P]
摘要
开发者分享了gocudrv的进展,这是一个为Go语言编写的无cgo的CUDA绑定,解释了线程亲和性的挑战并展示了示例代码。
在我们工作中,由于公司最近切换到了Rust,我们使用CUDA与Rust。Rust有相当不错的Driver API绑定,但让我不禁疑惑,为什么我们在Go里就没有一个不需要cgo的像样方案呢。过去一个月我主要构建ML工具,而Go是我几乎所有事情的首选语言。问题在于,大多数Go的CUDA项目仍然需要cgo以及完整的工具包在构建时。这破坏了交叉编译,并且使Docker镜像变得巨大,在处理机器学习项目时很烦人。所以上个月我开始捣鼓一个概念验证,使用purego在运行时加载[libcuda.so](http://libcuda.so)。完全不使用cgo。最大的痛点是线程亲和性。CUDA按线程保存上下文,所以goroutine切换会导致问题。我构建了一个简单的执行器,通过runtime.LockOSThread锁定一个OS线程,并通过一个通道传递所有调用。目前使用起来大概是这样:
func run() error {
cuda.Init()
dev, _ := cuda.GetDevice(0)
ctx, _ := dev.Primary()
defer ctx.Close()
a, _ := cuda.Alloc[float32](ctx, 1024)
b, _ := cuda.Alloc[float32](ctx, 1024)
c, _ := cuda.Alloc[float32](ctx, 1024)
stream, _ := ctx.NewStream()
start, _ := ctx.NewEvent()
stop, _ := ctx.NewEvent()
start.Record(stream)
fn.LaunchOn(bg, stream, cfg, cuda.Arg(a), cuda.Arg(b), cuda.Arg(c), cuda.ArgValue(int32(1024)),
)
stop.Record(stream)
stop.Synchronize()
duration, _ := start.Elapsed(stop)
fmt.Printf("GPU time: %v\n", duration)
return nil
}
在我的4070 Ti上,一个1000万元素的向量加法显示CPU计时大约160微秒,但实际GPU事件计时为434微秒。这个差异让我惊讶。这个项目仍然非常早期,进展缓慢,因为我只在周末编码,而且我对CUDA完全是个新手。正在慢慢添加Graph和多GPU支持。这非常早期,所以请把它当作一个学习CUDA的仓库,但我学习CUDA觉得很有趣。我想你们中有些人可能也会觉得它有意思。仓库在[github.com/eitamring/gocudrv](http://github.com/eitamring/gocudrv),如果你想看看。如果任何拥有5xxx系列显卡的人想试试,那就太好了(眨眼)
相似文章
@npashi: 终于可以谈谈过去6个月我在@nvidia一直埋头做的事了。我们刚刚开源了cuda-oxide——一个实验性…
NVIDIA 已开源 cuda-oxide,这是一个实验性的 rustc 后端,允许开发者直接用纯 Rust 编写 CUDA 内核,无需 DSL、FFI 或源码到源码的转换。
优化CPU密集型Go热路径的笔记
本文讨论了CPU密集型Go代码的性能优化技术,指出了泛型和接口抽象因无法内联而产生的局限性,并主张在热路径中使用代码复制。文章通过一个Brotli移植示例和深入基准测试进行了说明。
cuda-oxide 手册
cuda-oxide 是一个实验性的 Rust 到 CUDA 编译器,允许开发者编写安全、符合 Rust 惯用法的 GPU 内核,并直接编译为 PTX。
@levidiamode: Day 138/365 of GPU Programming 今年我最喜欢的讲座之一是斯坦福大学的CS336第7讲关于GPU…
一位学习者分享了对斯坦福大学CS336第7讲关于GPU并行性的热情,该讲座涵盖了基本操作,并将其连接到多GPU设置以及张量并行、数据并行和流水线并行等技术。
llama.cpp b9095 发布!支持双 Blackwell PCIe 显卡无需 NCCL 的张量并行
llama.cpp b9095 版本引入了针对双 Blackwell PCIe GPU 的免 NCCL 张量并行功能,使得在不依赖 NCCL 的情况下也能实现高效的多 GPU 推理。