use super::Scalar;
use core::mem::MaybeUninit;
mod trsm;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Op {
N,
T,
C,
}
impl Op {
#[inline(always)]
fn at<T: Scalar>(self, a: &[T], ld: usize, i: usize, j: usize) -> T {
match self {
Op::N => a[i + j * ld],
Op::T => a[j + i * ld],
Op::C => a[j + i * ld].conj(),
}
}
}
#[allow(clippy::too_many_arguments)]
#[track_caller]
pub(crate) fn gemm<T: Scalar>(
m: usize,
n: usize,
k: usize,
alpha: T,
a: &[T],
lda: usize,
opa: Op,
b: &[T],
ldb: usize,
opb: Op,
beta: T,
c: &mut [T],
ldc: usize,
) {
T::gemm(m, n, k, alpha, a, lda, opa, b, ldb, opb, beta, c, ldc);
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) enum Side {
Left,
Right,
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) enum Uplo {
Upper,
Lower,
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn trsm<T: Scalar>(
side: Side,
uplo: Uplo,
op: Op,
unit: bool,
m: usize,
n: usize,
a: &[T],
lda: usize,
b: &mut [T],
ldb: usize,
) {
trsm::solve(side, uplo, op, unit, m, n, a, lda, b, ldb);
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn trsm_into<T: Scalar>(
uplo: Uplo,
op: Op,
unit: bool,
m: usize,
n: usize,
a: &[T],
lda: usize,
b: &mut [T],
ldb: usize,
x: &mut [T],
ldx: usize,
) {
trsm::solve_into(uplo, op, unit, m, n, a, lda, b, ldb, x, ldx);
}
const SCRATCH: usize = 1024;
pub(crate) fn with_scratch<T: Scalar, X>(len: usize, f: impl FnOnce(&mut [T]) -> X) -> X {
if len <= SCRATCH {
let mut s = [const { MaybeUninit::<T>::uninit() }; SCRATCH];
for v in &mut s[..len] {
v.write(T::zero());
}
f(unsafe { &mut *(&mut s[..len] as *mut [MaybeUninit<T>] as *mut [T]) })
} else {
f(&mut vec![T::zero(); len])
}
}