Rust通用工具库cubecl-common的使用,cubecl-common提供高效实用的Rust基础功能模块
Rust通用工具库cubecl-common的使用
cubecl-common是一个高效实用的Rust基础功能模块,为GPU计算提供多平台高性能计算语言扩展。
示例代码
以下是使用cubecl-common的GELU激活函数实现示例:
use cubecl::prelude::*;
#[cube(launch_unchecked)]
/// A [Line] represents a contiguous series of elements where SIMD operations may be available.
/// The runtime will automatically use SIMD instructions when possible for improved performance.
fn gelu_array<F: Float>(input: &Array<Line<F>>, output: &mut Array<Line<F>>) {
if ABSOLUTE_POS < input.len() {
output[ABSOLUTE_POS] = gelu_scalar(input[ABSOLUTE_POS]);
}
}
#[cube]
fn gelu_scalar<F: Float>(x: Line<F>) -> Line<F> {
// Execute the sqrt function at comptime.
let sqrt2 = F::new(comptime!(2.0f32.sqrt()));
let tmp = x / Line::new(sqrt2);
x * (Line::erf(tmp) + 1.0) / 2.0
}
然后可以使用自动生成的gelu_array::launch_unchecked
函数启动内核:
pub fn launch<R: Runtime>(device: &R::Device) {
let client = R::client(device);
let input = &[-1., 0., 1., 5.];
let vectorization = 4;
let output_handle = client.empty(input.len() * core::mem::size_of::<f32>());
let input_handle = client.create(f32::as_bytes(input));
unsafe {
gelu_array::launch_unchecked::<f32, R>(
&client,
CubeCount::Static(1, 1, 1),
CubeDim::new(input.len() as u32 / vectorization, 1, 1),
ArrayArg::from_raw_parts::<f32](&input_handle, input.len(), vectorization as u8),
ArrayArg::from_raw_parts::<f32](&output_handle, input.len(), vectorization as u8),
)
};
let bytes = client.read_one(output_handle.binding());
let output = f32::from_bytes(&bytes);
// Should be [-0.1587, 0.0000, 0.8413, 5.0000]
println!("Executed gelu with runtime {:?} => {output:?}", R::name());
}
要查看实际效果,可以使用以下命令运行GELU示例:
cargo run --example gelu --features cuda # cuda runtime
cargo run --example gelu --features wgpu # wgpu runtime
完整示例
以下是一个完整的示例,展示了如何使用cubecl-common库:
use cubecl::prelude::*;
// 定义GELU激活函数
#[cube]
fn gelu_scalar<F: Float>(x: Line<F>) -> Line<F> {
let sqrt2 = F::new(comptime!(2.0f32.sqrt()));
let tmp = x / Line::new(sqrt2);
x * (Line::erf(tmp) + 1.0) / 2.0
}
// 定义数组操作的GELU函数
#[cube(launch_unchecked)]
fn gelu_array<F: Float>(input: &Array<Line<F>>, output: &mut Array<Line<F>>) {
if ABSOLUTE_POS < input.len() {
output[ABSOLUTE_POS] = gelu_scalar(input[ABSOLUTE_POS]);
}
}
// 主函数
fn main() {
// 初始化CUDA运行时
let device = cubecl::cuda::Device::default();
// 准备输入数据
let input_data = vec![-1.0f32, 0.0, 1.0, 5.0];
// 创建客户端
let client = cubecl::cuda::client(&device);
// 创建输入和输出缓冲区
let input_handle = client.create(f32::as_bytes(&input_data));
let output_handle = client.empty(input_data.len() * std::mem::size_of::<f32>());
// 设置向量化因子
let vectorization = 4;
// 启动内核
unsafe {
gelu_array::launch_unchecked::<f32, cubecl::cuda::Runtime>(
&client,
CubeCount::Static(1, 1, 1),
CubeDim::new(input_data.len() as u32 / vectorization, 1, 1),
ArrayArg::from_raw_parts::<f32](&input_handle, input_data.len(), vectorization as u8),
ArrayArg::from_raw_parts::<f32](&output_handle, input_data.len(), vectorization as u8),
);
}
// 读取结果
let output_bytes = client.read_one(output_handle.binding());
let output = f32::from_bytes(&output_bytes);
println!("Input: {:?}", input_data);
println!("Output: {:?}", output);
}
特性
cubecl-common提供了以下核心特性:
- 自动向量化 - 可以指定每个输入变量的向量化因子,运行时能够编译内核并使用最佳指令
- Comptime - 允许在首次编译内核时修改编译器IR,实现各种优化和灵活性
- 自动调优 - 在运行时运行小型基准测试以确定当前硬件上最佳的内核和配置
支持平台
cubecl-common支持多种平台和运行时:
平台 | 运行时 | 编译器 | 硬件 |
---|---|---|---|
WebGPU | wgpu | WGSL | 大多数GPU |
CUDA | CUDA | C++ (CUDA) | NVIDIA GPU |
ROCm | HIP | C++ (HIP) | AMD GPU |
Metal | wgpu | C++ (Metal) | Apple GPU |
Vulkan | wgpu | SPIR-V | Linux和Windows上的大多数GPU |
安装
要使用cubecl-common,可以将以下内容添加到您的Cargo.toml中:
[dependencies]
cubecl-common = "0.6.0"
或者运行以下Cargo命令:
cargo add cubecl-common
1 回复
cubecl-common - Rust通用工具库使用指南
概述
cubecl-common是一个高效实用的Rust基础功能模块集合,提供了日常开发中常用的工具函数和数据结构,帮助开发者提高开发效率。
主要功能
1. 常用数据结构
提供了一些扩展的数据结构实现:
use cubecl_common::collections::{
DoubleLinkedList,
CircularBuffer,
PriorityQueue
};
fn main() {
// 双向链表示例
let mut list = DoubleLinkedList::new();
list.push_front(1);
list.push_back(2);
// 环形缓冲区示例
let mut buf = CircularBuffer::with_capacity(5);
buf.push(1);
buf.push(2);
// 优先队列示例
let mut pq = PriorityQueue::new();
pq.push("task1", 3);
pq.push("task2", 1);
}
2. 字符串处理
提供了一系列字符串处理工具:
use cubecl_common::string_utils::{
camel_to_snake,
snake_to_camel,
truncate_string
};
fn main() {
// 驼峰转蛇形
let s = camel_to_snake("HelloWorld"); // "hello_world"
// 蛇形转驼峰
let s = snake_to_camel("hello_world"); // "HelloWorld"
// 字符串截断
let s = truncate_string("This is a long string", 10); // "This is a..."
}
3. 日期时间处理
简化日期时间操作:
use cubecl_common::datetime::{
current_timestamp,
format_timestamp,
days_between
};
fn main() {
// 获取当前时间戳
let now = current_timestamp();
// 格式化时间戳
let formatted = format_timestamp(now, "%Y-%m-%d %H:%M:%S");
// 计算两个日期之间的天数
let days = days_between("2023-01-01", "2023-01-10");
}
4. 文件系统操作
提供便捷的文件系统API:
use cubecl_common::fs_utils::{
read_file_to_string,
write_string_to_file,
ensure_dir_exists
};
fn main() -> std::io::Result<()> {
// 确保目录存在
ensure_dir_exists("/path/to/dir")?;
// 写入文件
write_string_to_file("/path/to/file.txt", "Hello, world!")?;
// 读取文件
let content = read_file_to_string("/path/to/file.txt)?;
Ok(())
}
5. 加密哈希工具
提供常用哈希算法:
use cubecl_common::crypto::{
md5_hash,
sha256_hash,
generate_salt
};
fn main() {
// MD5哈希
let hash = md5_hash("password");
// SHA256哈希
let hash = sha256_hash("password");
// 生成随机盐值
let salt = generate_salt(16);
}
完整示例代码
//! cubecl-common 综合使用示例
use cubecl_common::prelude::*;
use cubecl_common::collections::{DoubleLinkedList, PriorityQueue};
use cubecl_common::string_utils::{camel_to_snake, truncate_string};
use cubecl_common::datetime::{current_timestamp, format_timestamp};
use cubecl_common::fs_utils::{read_file_to_string, write_string_to_file, ensure_dir_exists};
use cubecl_common::crypto::{sha256_hash, generate_salt};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 数据结构使用
let mut list = DoubleLinkedList::new();
list.push_front("item1");
list.push_back("item2");
let mut pq = PriorityQueue::new();
pq.push("高优先级任务", 1);
pq.push("低优先级任务", 3);
// 2. 字符串处理
let snake_case = camel_to_snake("UserAccountInfo");
println!("驼峰转蛇形: {}", snake_case);
let truncated = truncate_string("这是一段很长的文本需要截断处理", 8);
println!("截断后的字符串: {}", truncated);
// 3. 日期时间处理
let now = current_timestamp();
let formatted_time = format_timestamp(now, "%Y-%m-%d %H:%M:%S");
println!("当前时间: {}", formatted_time);
// 4. 文件操作
ensure_dir_exists("data")?;
write_string_to_file("data/example.txt", "测试文件内容")?;
let content = read_file_to_string("data/example.txt")?;
println!("文件内容: {}", content);
// 5. 加密哈希
let password_hash = sha256_hash("my_password");
let salt = generate_salt(32);
println!("密码哈希: {:?}", password_hash);
println!("生成盐值: {:?}", salt);
Ok(())
}
安装方法
在Cargo.toml中添加依赖:
[dependencies]
cubecl-common = "0.1.0" # 请使用最新版本
性能特点
- 零成本抽象:尽可能使用Rust的零成本抽象特性
- 无恐慌API:关键函数都提供了Result返回
- 线程安全:主要数据结构都实现了Send+Sync
最佳实践
use cubecl_common::prelude::*; // 导入常用功能
fn process_data() -> Result<(), CommonError> {
// 使用工具函数处理数据
let data = read_file_to_string("input.txt")?;
let processed = data.to_uppercase();
ensure_dir_exists("output")?;
write_string_to_file("output/result.txt", &processed)?;
Ok(())
}
注意事项
- 某些功能可能需要启用特定feature
- 生产环境使用时建议锁定版本号
- 详细API文档请参考crate文档
cubecl-common持续更新中,欢迎贡献代码和提出建议!