#vulkan #gpu #kernel #compute

krnl

安全、便携、高性能计算(GPGPU)内核

6个版本

0.1.1 2024年5月28日
0.1.0 2024年3月28日
0.0.4 2024年1月31日
0.0.3 2023年10月17日
0.0.2 2023年4月23日

#86 in 数学

Download history 1/week @ 2024-04-29 42/week @ 2024-05-13 2/week @ 2024-05-20 229/week @ 2024-05-27 14/week @ 2024-06-03 14/week @ 2024-06-10 10/week @ 2024-06-17 1/week @ 2024-06-24 8/week @ 2024-07-01 158/week @ 2024-07-08 32/week @ 2024-07-15 64/week @ 2024-07-22 45/week @ 2024-07-29 34/week @ 2024-08-05 23/week @ 2024-08-12

每月 166 次下载
用于 autograph

MIT/Apache

335KB
6K SLoC

DocsBadge build

krnl

安全、便携、高性能计算(GPGPU)内核。

autograph 开发。

  • 与CUDA和OpenCL具有相似的功能。
  • 支持GPU和其他Vulkan 1.2兼容设备。
  • 通过 MoltenVK 支持MacOS / iOS。
  • 内核以Rust编写,全部是内联的。
    • 可以通过简单的迭代模式实现,无需使用unsafe。
    • 支持内联 SPIR-V 汇编。
    • 集成DebugPrintf,生成panic的回溯。
  • 主机上的缓冲区可以原生地作为Vecs和slices访问。

krnlc

krnl的内核编译器。

  • 基于 spirv-builder 构建。
  • 支持在Cargo.toml中定义的依赖关系。
  • 使用 spirv-tools 进行验证和优化。
  • 编译到 "krnl-cache.rs",因此该包将在稳定版Rust上构建。

请参阅文档以获取安装和使用说明。

安装

对于设备功能(内核),为您的平台安装 Vulkan

  • 对于开发,建议安装包含额外工具的 LunarG Vulkan SDK
    • vulkaninfo
    • 验证层
      • DebugPrintf
    • spirv-tools
      • 这被krnlc用于SPIR-V验证和优化。
        • krnlc默认构建,无需安装spirv-tools。

测试

  • 检查 vulkaninfo --summary 是否显示您的设备。
    • 实例版本应大于等于1.2。
  • 或者,检查 cargo test --test integration_tests -- --exact none 是否显示了您的设备。
    • 您可以使用 cargo test --all-features 运行所有测试。

入门指南

查看文档或使用 cargo doc --all-features 在本地构建。

示例

use krnl::{
    macros::module,
    anyhow::Result,
    device::Device,
    buffer::{Buffer, Slice, SliceMut},
};

#[module]
mod kernels {
    #[cfg(not(target_arch = "spirv"))]
    use krnl::krnl_core;
    use krnl_core::macros::kernel;

    pub fn saxpy_impl(alpha: f32, x: f32, y: &mut f32) {
        *y += alpha * x;
    }

    // Item kernels for iterator patterns.
    #[kernel]
    pub fn saxpy(alpha: f32, #[item] x: f32, #[item] y: &mut f32) {
        saxpy_impl(alpha, x, y);
    }

    // General purpose kernels like CUDA / OpenCL.
    #[kernel]
    pub fn saxpy_global(alpha: f32, #[global] x: Slice<f32>, #[global] y: UnsafeSlice<f32>) {
        use krnl_core::buffer::UnsafeIndex;

        let global_id = kernel.global_id();
        if global_id < x.len().min(y.len()) {
            saxpy_impl(alpha, x[global_id], unsafe { y.unsafe_index_mut(global_id) });
        }
    }
}

fn saxpy(alpha: f32, x: Slice<f32>, mut y: SliceMut<f32>) -> Result<()> {
    if let Some((x, y)) = x.as_host_slice().zip(y.as_host_slice_mut()) {
        x.iter()
            .copied()
            .zip(y.iter_mut())
            .for_each(|(x, y)| kernels::saxpy_impl(alpha, x, y));
        return Ok(());
    }
    if true {
        kernels::saxpy::builder()?
            .build(y.device())?
            .dispatch(alpha, x, y)
    } else {
        // or
        kernels::saxpy_global::builder()?
            .build(y.device())?
            .with_global_threads(y.len() as u32)
            .dispatch(alpha, x, y)
    }
}

fn main() -> Result<()> {
    let x = vec![1f32];
    let alpha = 2f32;
    let y = vec![0f32];
    let device = Device::builder().build().ok().unwrap_or(Device::host());
    let x = Buffer::from(x).into_device(device.clone())?;
    let mut y = Buffer::from(y).into_device(device.clone())?;
    saxpy(alpha, x.as_slice(), y.as_slice_mut())?;
    let y = y.into_vec()?;
    println!("{y:?}");
    Ok(())
}

性能

NVIDIA GeForce GTX 1060 Max-Q设计

benches/compute-benches

alloc

krnl cuda ocl
1,000,000 316.90 ns (✅ 1.00x) 112.84 us (❌ 356.06x 慢) 495.45 ns (❌ 1.56x 慢)
10,000,000 318.15 ns (✅ 1.00x) 1.10 ms (❌ 3454.98x 慢) 506.82 ns (❌ 1.59x 慢)
64,000,000 317.56 ns (✅ 1.00x) 6.31 ms (❌ 19854.77x 慢) 506.15 ns (❌ 1.59x 慢)

upload

krnl cuda ocl
1,000,000 332.66 us (✅ 1.00x) 359.18 us (✅ 1.08x 慢) 773.51 us (❌ 2.33x 慢)
10,000,000 4.83 ms (✅ 1.00x) 3.69 ms (✅ 1.31x 快) 8.76 ms (❌ 1.81x 慢)
64,000,000 25.24 ms (✅ 1.00x) 24.34 ms (✅ 1.04x 快) 57.02 ms (❌ 2.26x 慢)

download

krnl cuda ocl
1,000,000 584.39 us (✅ 1.00x) 447.38 us (✅ 1.31x 快) 20.17 ms (❌ 34.52x 慢)
10,000,000 5.67 ms (✅ 1.00x) 4.03 ms (✅ 1.41x 快) 20.15 ms (❌ 3.55x 慢)
64,000,000 28.82 ms (✅ 1.00x) 25.57 毫秒 (✅ 1.13 倍更快) 37.01 毫秒 (❌ 1.28 倍更慢)

krnl cuda ocl
1,000,000 38.15 微秒 (✅ 1.00 倍) 25.28 微秒 (✅ 1.51 倍更快) 34.12 微秒 (✅ 1.12 倍更快)
10,000,000 250.90 微秒 (✅ 1.00 倍) 242.95 微秒 (✅ 1.03 倍更快) 251.86 微秒 (✅ 1.00 倍更慢)
64,000,000 1.53 毫秒 (✅ 1.00 倍) 1.55 毫秒 (✅ 1.01 倍更慢) 1.56 毫秒 (✅ 1.02 倍更慢)

saxpy

krnl cuda ocl
1,000,000 90.76 微秒 (✅ 1.00 倍) 81.16 微秒 (✅ 1.12 倍更快) 88.94 微秒 (✅ 1.02 倍更快)
10,000,000 746.92 微秒 (✅ 1.00 倍) 770.03 微秒 (✅ 1.03 倍更慢) 779.90 微秒 (✅ 1.04 倍更慢)
64,000,000 4.71 毫秒 (✅ 1.00 倍) 4.90 毫秒 (✅ 1.04 倍更慢) 4.91 毫秒 (✅ 1.04 倍更慢)

许可证

双重授权以兼容Rust项目。

根据您的选择,在Apache License,版本2.0 http://www.apache.org/licenses/LICENSE-2.0 或MIT许可证 http://opensource.org/licenses/MIT 下授权。此文件不得复制、修改或分发,除非根据这些条款。

贡献

除非您明确表示,否则您有意提交的任何贡献,根据Apache-2.0许可证定义的工作,应按上述方式双重授权,没有附加条款或条件。

依赖项

~8–17MB
~287K SLoC