use super::sys::{self};
use core::ffi::c_void;
use core::mem::MaybeUninit;
pub struct RocblasError(pub sys::rocblas_status);
impl sys::rocblas_status {
pub fn result(self) -> Result<(), RocblasError> {
match self {
sys::rocblas_status::rocblas_status_success => Ok(()),
_ => Err(RocblasError(self)),
}
}
}
impl std::fmt::Debug for RocblasError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("RocblasError").field(&self.0).finish()
}
}
impl std::fmt::Display for RocblasError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}
impl std::error::Error for RocblasError {}
pub fn create_handle() -> Result<sys::rocblas_handle, RocblasError> {
let mut handle = MaybeUninit::uninit();
unsafe {
sys::rocblas_create_handle(handle.as_mut_ptr()).result()?;
Ok(handle.assume_init())
}
}
pub unsafe fn destroy_handle(handle: sys::rocblas_handle) -> Result<(), RocblasError> {
unsafe { sys::rocblas_destroy_handle(handle).result() }
}
pub unsafe fn set_stream(
handle: sys::rocblas_handle,
stream: sys::hipStream_t,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_set_stream(handle, stream).result() }
}
pub unsafe fn set_pointer_mode(
handle: sys::rocblas_handle,
mode: sys::rocblas_pointer_mode,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_set_pointer_mode(handle, mode).result() }
}
pub unsafe fn sgemv(
handle: sys::rocblas_handle,
trans: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
alpha: *const f32,
a: *const f32,
lda: sys::rocblas_int,
x: *const f32,
incx: sys::rocblas_int,
beta: *const f32,
y: *mut f32,
incy: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_sgemv(handle, trans, m, n, alpha, a, lda, x, incx, beta, y, incy).result()
}
}
pub unsafe fn dgemv(
handle: sys::rocblas_handle,
trans: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
alpha: *const f64,
a: *const f64,
lda: sys::rocblas_int,
x: *const f64,
incx: sys::rocblas_int,
beta: *const f64,
y: *mut f64,
incy: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_dgemv(handle, trans, m, n, alpha, a, lda, x, incx, beta, y, incy).result()
}
}
pub unsafe fn hgemm(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const half::f16,
a: *const half::f16,
lda: sys::rocblas_int,
b: *const half::f16,
ldb: sys::rocblas_int,
beta: *const half::f16,
c: *mut half::f16,
ldc: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_hgemm(
handle,
transa,
transb,
m,
n,
k,
alpha as *const sys::rocblas_half,
a as *const sys::rocblas_half,
lda,
b as *const sys::rocblas_half,
ldb,
beta as *const sys::rocblas_half,
c as *mut sys::rocblas_half,
ldc,
)
.result()
}
}
pub unsafe fn sgemm(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const f32,
a: *const f32,
lda: sys::rocblas_int,
b: *const f32,
ldb: sys::rocblas_int,
beta: *const f32,
c: *mut f32,
ldc: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_sgemm(
handle, transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc,
)
.result()
}
}
pub unsafe fn dgemm(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const f64,
a: *const f64,
lda: sys::rocblas_int,
b: *const f64,
ldb: sys::rocblas_int,
beta: *const f64,
c: *mut f64,
ldc: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_dgemm(
handle, transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc,
)
.result()
}
}
#[allow(clippy::too_many_arguments)]
pub unsafe fn hgemm_strided_batched(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const half::f16,
a: *const half::f16,
lda: sys::rocblas_int,
stride_a: sys::rocblas_stride,
b: *const half::f16,
ldb: sys::rocblas_int,
stride_b: sys::rocblas_stride,
beta: *const half::f16,
c: *mut half::f16,
ldc: sys::rocblas_int,
stride_c: sys::rocblas_stride,
batch_count: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_hgemm_strided_batched(
handle,
transa,
transb,
m,
n,
k,
alpha as *const sys::rocblas_half,
a as *const sys::rocblas_half,
lda,
stride_a,
b as *const sys::rocblas_half,
ldb,
stride_b,
beta as *const sys::rocblas_half,
c as *mut sys::rocblas_half,
ldc,
stride_c,
batch_count,
)
.result()
}
}
#[allow(clippy::too_many_arguments)]
pub unsafe fn sgemm_strided_batched(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const f32,
a: *const f32,
lda: sys::rocblas_int,
stride_a: sys::rocblas_stride,
b: *const f32,
ldb: sys::rocblas_int,
stride_b: sys::rocblas_stride,
beta: *const f32,
c: *mut f32,
ldc: sys::rocblas_int,
stride_c: sys::rocblas_stride,
batch_count: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_sgemm_strided_batched(
handle,
transa,
transb,
m,
n,
k,
alpha,
a,
lda,
stride_a,
b,
ldb,
stride_b,
beta,
c,
ldc,
stride_c,
batch_count,
)
.result()
}
}
#[allow(clippy::too_many_arguments)]
pub unsafe fn dgemm_strided_batched(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const f64,
a: *const f64,
lda: sys::rocblas_int,
stride_a: sys::rocblas_stride,
b: *const f64,
ldb: sys::rocblas_int,
stride_b: sys::rocblas_stride,
beta: *const f64,
c: *mut f64,
ldc: sys::rocblas_int,
stride_c: sys::rocblas_stride,
batch_count: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_dgemm_strided_batched(
handle,
transa,
transb,
m,
n,
k,
alpha,
a,
lda,
stride_a,
b,
ldb,
stride_b,
beta,
c,
ldc,
stride_c,
batch_count,
)
.result()
}
}
#[allow(clippy::too_many_arguments)]
pub unsafe fn gemm_ex(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const c_void,
a: *const c_void,
a_type: sys::rocblas_datatype,
lda: sys::rocblas_int,
b: *const c_void,
b_type: sys::rocblas_datatype,
ldb: sys::rocblas_int,
beta: *const c_void,
c: *const c_void,
c_type: sys::rocblas_datatype,
ldc: sys::rocblas_int,
d: *mut c_void,
d_type: sys::rocblas_datatype,
ldd: sys::rocblas_int,
compute_type: sys::rocblas_datatype,
algo: sys::rocblas_gemm_algo,
solution_index: i32,
flags: u32,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_gemm_ex(
handle,
transa,
transb,
m,
n,
k,
alpha,
a,
a_type,
lda,
b,
b_type,
ldb,
beta,
c,
c_type,
ldc,
d,
d_type,
ldd,
compute_type,
algo,
solution_index,
flags,
)
.result()
}
}
#[allow(clippy::too_many_arguments)]
pub unsafe fn gemm_strided_batched_ex(
handle: sys::rocblas_handle,
transa: sys::rocblas_operation,
transb: sys::rocblas_operation,
m: sys::rocblas_int,
n: sys::rocblas_int,
k: sys::rocblas_int,
alpha: *const c_void,
a: *const c_void,
a_type: sys::rocblas_datatype,
lda: sys::rocblas_int,
stride_a: sys::rocblas_stride,
b: *const c_void,
b_type: sys::rocblas_datatype,
ldb: sys::rocblas_int,
stride_b: sys::rocblas_stride,
beta: *const c_void,
c: *const c_void,
c_type: sys::rocblas_datatype,
ldc: sys::rocblas_int,
stride_c: sys::rocblas_stride,
d: *mut c_void,
d_type: sys::rocblas_datatype,
ldd: sys::rocblas_int,
stride_d: sys::rocblas_stride,
batch_count: sys::rocblas_int,
compute_type: sys::rocblas_datatype,
algo: sys::rocblas_gemm_algo,
solution_index: i32,
flags: u32,
) -> Result<(), RocblasError> {
unsafe {
sys::rocblas_gemm_strided_batched_ex(
handle,
transa,
transb,
m,
n,
k,
alpha,
a,
a_type,
lda,
stride_a,
b,
b_type,
ldb,
stride_b,
beta,
c,
c_type,
ldc,
stride_c,
d,
d_type,
ldd,
stride_d,
batch_count,
compute_type,
algo,
solution_index,
flags,
)
.result()
}
}
pub unsafe fn sasum(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f32,
incx: sys::rocblas_int,
result: *mut f32,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_sasum(handle, n, x, incx, result).result() }
}
pub unsafe fn dasum(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f64,
incx: sys::rocblas_int,
result: *mut f64,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_dasum(handle, n, x, incx, result).result() }
}
pub unsafe fn snrm2(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f32,
incx: sys::rocblas_int,
result: *mut f32,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_snrm2(handle, n, x, incx, result).result() }
}
pub unsafe fn dnrm2(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f64,
incx: sys::rocblas_int,
result: *mut f64,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_dnrm2(handle, n, x, incx, result).result() }
}
pub unsafe fn sdot(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f32,
incx: sys::rocblas_int,
y: *const f32,
incy: sys::rocblas_int,
result: *mut f32,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_sdot(handle, n, x, incx, y, incy, result).result() }
}
pub unsafe fn ddot(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f64,
incx: sys::rocblas_int,
y: *const f64,
incy: sys::rocblas_int,
result: *mut f64,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_ddot(handle, n, x, incx, y, incy, result).result() }
}
pub unsafe fn saxpy(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
alpha: *const f32,
x: *const f32,
incx: sys::rocblas_int,
y: *mut f32,
incy: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_saxpy(handle, n, alpha, x, incx, y, incy).result() }
}
pub unsafe fn daxpy(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
alpha: *const f64,
x: *const f64,
incx: sys::rocblas_int,
y: *mut f64,
incy: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_daxpy(handle, n, alpha, x, incx, y, incy).result() }
}
pub unsafe fn sscal(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
alpha: *const f32,
x: *mut f32,
incx: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_sscal(handle, n, alpha, x, incx).result() }
}
pub unsafe fn dscal(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
alpha: *const f64,
x: *mut f64,
incx: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_dscal(handle, n, alpha, x, incx).result() }
}
pub unsafe fn scopy(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f32,
incx: sys::rocblas_int,
y: *mut f32,
incy: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_scopy(handle, n, x, incx, y, incy).result() }
}
pub unsafe fn dcopy(
handle: sys::rocblas_handle,
n: sys::rocblas_int,
x: *const f64,
incx: sys::rocblas_int,
y: *mut f64,
incy: sys::rocblas_int,
) -> Result<(), RocblasError> {
unsafe { sys::rocblas_dcopy(handle, n, x, incx, y, incy).result() }
}