4 个版本

0.1.3 2021 年 7 月 28 日
0.1.2 2020 年 2 月 29 日
0.1.1 2019 年 5 月 17 日
0.1.0 2018 年 12 月 1 日

#77图形 API

Download history 1030/week @ 2024-02-27 2162/week @ 2024-03-05 863/week @ 2024-03-12 631/week @ 2024-03-19 1030/week @ 2024-03-26 742/week @ 2024-04-02 884/week @ 2024-04-09 414/week @ 2024-04-16 575/week @ 2024-04-23 203/week @ 2024-04-30 315/week @ 2024-05-07 261/week @ 2024-05-14 164/week @ 2024-05-21 282/week @ 2024-05-28 264/week @ 2024-06-04 191/week @ 2024-06-11

938 每月下载量
用于 6 软件包

Apache-2.0 OR MIT

305KB
4K SLoC

RustaCUDA

RustaCUDA 是 Rust 编程语言访问 NVIDIA® CUDA™ 驱动 API 的高级接口

RustaCUDA 通过提供灵活、易于使用的接口,帮助您将 GPU 加速功能引入项目。RustaCUDA 使管理 GPU 内存、在 GPU 之间传输数据以及加载和启动用任何语言编写的计算内核变得简单。

目录

目标

主要设计目标包括

  • 高级:使用 RustaCUDA 应该对 Rust 程序员来说既熟悉又直观。
  • 易于使用:RustaCUDA 应具有良好的文档和设计,足以帮助初学者开始 GPU 编程,同时不会过多限制经验更丰富的用户。
  • 安全:许多 GPU 加速计算的方面难以与 Rust 的安全保证相协调,但 RustaCUDA 应该提供合理实用的最安全接口。
  • 快速:RustaCUDA 应该尽可能地快,在不与其他目标冲突的情况下。

RustaCUDA 旨在提供一个面向程序员的库,用于与主机端的 CUDA 驱动 API 一起工作。它不旨在帮助将 Rust 代码编译为 CUDA 内核(尽管您可以查看 rust-ptx-builder 了解相关信息)或提供在内核内部使用的设备端实用程序。

RustaCUDA 故意对内核的工作方式或编译方式保持中立。这使得可以使用用 nvcc 编译的 C 内核(例如)。

路线图

RustaCUDA 目前支持 CUDA API 的最小可行子集(基本上,是管理内存和启动基本内核所需的最小内容)。这不包括

  • 除了内核启动之外的所有异步操作
  • 访问 CUDA 1/2/3D 数组和纹理内存
  • 多 GPU 支持
  • 运行时链接
  • CUDA 图
  • 等等!

这些附加功能将在有时间且必要时进行开发。如果您需要尚未支持的功能,请考虑提交一个pull request!

快速入门

在使用RustaCUDA之前,您必须安装适用于您的系统的CUDA开发库。需要版本8.0或更高版本。您还必须安装带有适当驱动程序的CUDA兼容GPU。

首先,将环境变量CUDA_LIBRARY_PATH设置为CUDA头文件的位置

export CUDA_LIBRARY_PATH="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.1\lib\x64"

一些Ubuntu用户在使用CUDA_LIBRARY_PATH时遇到了链接错误。如果您看到如下错误

  = note: /usr/bin/ld: cannot find -lcudart                                                              
          /usr/bin/ld: cannot find -lcublas                                                              
          collect2: error: ld returned 1 exit status 

使用LIBRARY_PATH而不是CUDA_LIBRARY_PATH似乎有帮助。

现在,开始构建一个基本的CUDA crate。将以下内容添加到您的Cargo.toml

[dependencies]
rustacuda = "0.1"
rustacuda_core = "0.1"
rustacuda_derive = "0.1"

并将其添加到crate根目录下

#[macro_use]
extern crate rustacuda;

#[macro_use]
extern crate rustacuda_derive;
extern crate rustacuda_core;

接下来,从RustaCUDA仓库下载resources/add.ptx文件,并将其放置在您的应用程序的资源目录中。

examples/目录中包含了一些示例代码,可以帮助您入门。要执行最简单的示例(在GPU上添加两个数字),将以下代码放置到您的main.rs文件中。

#[macro_use]
extern crate rustacuda;

use rustacuda::prelude::*;
use rustacuda::memory::DeviceBox;
use std::error::Error;
use std::ffi::CString;

fn main() -> Result<(), Box<dyn Error>> {
    // Initialize the CUDA API
    rustacuda::init(CudaFlags::empty())?;
    
    // Get the first device
    let device = Device::get_device(0)?;

    // Create a context associated to this device
    let context = Context::create_and_push(
        ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device)?;

    // Load the module containing the function we want to call
    let module_data = CString::new(include_str!("../resources/add.ptx"))?;
    let module = Module::load_from_string(&module_data)?;

    // Create a stream to submit work to
    let stream = Stream::new(StreamFlags::NON_BLOCKING, None)?;

    // Allocate space on the device and copy numbers to it.
    let mut x = DeviceBox::new(&10.0f32)?;
    let mut y = DeviceBox::new(&20.0f32)?;
    let mut result = DeviceBox::new(&0.0f32)?;

    // Launching kernels is unsafe since Rust can't enforce safety - think of kernel launches
    // as a foreign-function call. In this case, it is - this kernel is written in CUDA C.
    unsafe {
        // Launch the `sum` function with one block containing one thread on the given stream.
        launch!(module.sum<<<1, 1, 0, stream>>>(
            x.as_device_ptr(),
            y.as_device_ptr(),
            result.as_device_ptr(),
            1 // Length
        ))?;
    }

    // The kernel launch is asynchronous, so we wait for the kernel to finish executing
    stream.synchronize()?;

    // Copy the result back to the host
    let mut result_host = 0.0f32;
    result.copy_to(&mut result_host)?;
    
    println!("Sum is {}", result_host);

    Ok(())
}

如果一切正常,您应该能够运行cargo run并看到输出

Sum is 30.0

贡献

感谢您的兴趣!欢迎贡献。

请通过上面的issue tracker报告问题、功能请求、疑问和错误报告。特别是,因为RustaCUDA旨在提供良好的文档,请报告任何您认为混乱或不正确的文档内容。

以pull request形式提出的代码或文档改进也是受欢迎的。不过,请在大量工作之前先提交或评论一个issue以允许讨论。

有关更多详细信息,请参阅CONTRIBUTING.md文件

维护

RustaCUDA目前由Brook Heisler (@bheisler) 维护。

许可证

RustaCUDA根据Apache 2.0许可证和MIT许可证双授权。

要求

RustaCUDA需要安装至少CUDA版本8。

  • accel是一个完整的CUDA计算框架。感谢accel创建了并维护了cuda-sys FFI包装库。
  • rust-ptx-builder是一个build.rs辅助库,它使将Rust crate编译成CUDA内核变得简单。

依赖关系

~1.5MB
~44K SLoC