You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust调用cuBLAS的cublasCreate_v2函数遇编译错误求助

解决cuBLAS绑定中cublasCreate_v2的编译错误

问题背景

尝试用bindgen为cuBLAS生成绑定,测试代码编译时出现错误,核心问题是调用cublasCreate_v2的方式不正确。

测试代码

mod tests {
    use super::*;

    #[test]
    pub fn alpha () {
        let mut handle: cublasHandle_t;
        let mut stat: cublasStatus_t;
        let mut cudaStat: cudaError_t;

       ... some stuff

        unsafe {
            cudaStat = cudaMalloc(a.as_mut_ptr() as *mut *mut c_void, a.len() as u64);
            cudaStat = cudaMalloc(b.as_mut_ptr() as *mut *mut c_void, b.len() as u64);
            cudaStat = cudaMalloc(c.as_mut_ptr() as *mut *mut c_void, c.len() as u64);

            stat = cublasCreate_v2(handle as *mut *mut cublasContext);
        }

        ...some stuff
    }
}

编译错误

error: expected expression, found keyword `mut`
  --> src/lib.rs:44:37
   |
44 |             stat = cublasCreate_v2(handle as *mut *mut cublasContext);
   |                                     ^^^ expected expression

error: could not compile `cublas-rs` due to previous error

绑定代码(bindings.rs)

// cublasContext struct we want to pass to cublasCreate_v2
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct cublasContext {
    _unused: [u8; 0],
}

// alternative typedef used by cublas
pub type cublasHandle_t = *mut cublasContext;

// function to create a cublas handle
extern "C" {
    pub fn cublasCreate_v2(handle: *mut cublasHandle_t) -> cublasStatus_t;
}

用户尝试过的错误初始化方式

let mut handle: cublasHandle_t = *mut cublasContext { _unused: [] }; // no luck
let mut handle: cublasHandle_t = cublasContext { _unused: [] } as *mut cublasContext; // no

解决方案

cublasCreate_v2的参数要求是*mut cublasHandle_t(即指向cublasHandle_t的指针),因为该函数需要修改传入的handle变量,将其初始化为有效的句柄。正确的调用步骤如下:

  1. 先将handle初始化为空指针(因为cublasHandle_t是指针类型,必须先有一个有效值);
  2. 调用函数时传入handle的可变地址,转换为*mut cublasHandle_t类型。

修正后的代码:

mod tests {
    use super::*;
    use std::ptr;

    #[test]
    pub fn alpha () {
        // 初始化handle为空指针
        let mut handle: cublasHandle_t = ptr::null_mut();
        let mut stat: cublasStatus_t;
        let mut cudaStat: cudaError_t;

       ... some stuff

        unsafe {
            cudaStat = cudaMalloc(a.as_mut_ptr() as *mut *mut c_void, a.len() as u64);
            cudaStat = cudaMalloc(b.as_mut_ptr() as *mut *mut c_void, b.len() as u64);
            cudaStat = cudaMalloc(c.as_mut_ptr() as *mut *mut c_void, c.len() as u64);

            // 传入handle的可变地址,转换为*mut cublasHandle_t
            stat = cublasCreate_v2(&mut handle as *mut cublasHandle_t);
            // 或者使用更安全的addr_of_mut!宏(Rust 1.51+)
            // stat = cublasCreate_v2(std::ptr::addr_of_mut!(handle));
        }

        ...some stuff
    }
}

关键说明

  • cublasHandle_t本身是*mut cublasContext,所以*mut cublasHandle_t等价于*mut *mut cublasContext,这正是cublasCreate_v2要求的参数类型;
  • 必须先初始化handle为null_mut(),因为未初始化的变量在Rust中无法被引用或取地址;
  • 使用&mut handle as *mut cublasHandle_t可以直接将可变引用转换为对应的原始指针,符合C函数的参数要求。

内容的提问来源于stack exchange,提问作者Rylan Yancey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:51:34