#[inline]
pub unsafe fn fused_add_gemm_batch_fallback(
in_frames: &[f32],
weights: &[f32],
bias: &[f32], out_frames: &mut [f32],
num_frames: usize,
do_bias: bool,
) {
if num_frames == 0 {
return;
}
let in_len = in_frames.len() / num_frames;
let out_len = out_frames.len() / num_frames;
for f in 0..num_frames {
unsafe {
fused_add_gemv_fallback(
in_frames.get_unchecked(f * in_len..(f + 1) * in_len),
weights,
bias,
out_frames.get_unchecked_mut(f * out_len..(f + 1) * out_len),
do_bias,
);
}
}
}
#[inline]
pub unsafe fn fused_add_gemv_fallback(
in_frame: &[f32],
weights: &[f32],
bias: &[f32],
out_frame: &mut [f32],
do_bias: bool,
) {
let out_len = out_frame.len();
let in_len = in_frame.len();
for (out_c, &b) in bias.iter().enumerate().take(out_len) {
let mut sum = if do_bias { b } else { 0.0 };
for in_c in 0..in_len {
unsafe {
let w = *weights.get_unchecked(in_c * out_len + out_c);
sum += *in_frame.get_unchecked(in_c) * w;
}
}
unsafe {
*out_frame.get_unchecked_mut(out_c) += sum;
}
}
}
#[inline]
pub unsafe fn gemv_overwrite_fallback(
in_frame: &[f32],
weights: &[f32],
bias: &[f32],
out_frame: &mut [f32],
do_bias: bool,
) {
let out_len = out_frame.len();
let in_len = in_frame.len();
for (out_c, &b) in bias.iter().enumerate().take(out_len) {
let mut sum = if do_bias { b } else { 0.0 };
for in_c in 0..in_len {
unsafe {
let w = *weights.get_unchecked(in_c * out_len + out_c);
sum += *in_frame.get_unchecked(in_c) * w;
}
}
unsafe {
*out_frame.get_unchecked_mut(out_c) = sum;
}
}
}
#[inline]
pub unsafe fn fused_gemm_residual_batch_fallback(
in_frames: &[f32],
weights: &[f32],
bias: &[f32],
residual: &[f32], out_frames: &mut [f32],
num_frames: usize,
do_bias: bool,
) {
if num_frames == 0 {
return;
}
let in_len = in_frames.len() / num_frames;
let out_len = out_frames.len() / num_frames;
for frame_idx in 0..num_frames {
unsafe {
for (out_c, &b) in bias.iter().enumerate().take(out_len) {
let mut sum = if do_bias { b } else { 0.0 };
for in_c in 0..in_len {
let w = *weights.get_unchecked(in_c * out_len + out_c);
sum += *in_frames.get_unchecked(frame_idx * in_len + in_c) * w;
}
*out_frames.get_unchecked_mut(frame_idx * out_len + out_c) =
sum + *residual.get_unchecked(frame_idx * out_len + out_c);
}
}
}
}
#[inline]
pub unsafe fn gemv_overwrite_bf16_fallback(
in_frame: &[u16],
weights: &[u16],
bias: &[f32],
out_frame: &mut [f32],
do_bias: bool,
) {
let out_len = out_frame.len();
let in_len = in_frame.len();
for (out_c, &b) in bias.iter().enumerate().take(out_len) {
let mut sum = if do_bias { b } else { 0.0 };
for in_c in 0..in_len {
unsafe {
let s = f32::from_bits((*in_frame.get_unchecked(in_c) as u32) << 16);
sum += s * f32::from_bits(
(*weights.get_unchecked(in_c * out_len + out_c) as u32) << 16,
);
}
}
unsafe {
*out_frame.get_unchecked_mut(out_c) = sum;
}
}
}
#[inline]
pub fn gemv_with_bias_f32_fallback(
in_frames: &[f32],
weights: &[f32],
bias: &[f32],
out_frames: &mut [f32],
num_frames: usize,
) {
if num_frames == 0 {
return;
}
let in_len = in_frames.len() / num_frames;
let out_len = out_frames.len() / num_frames;
for n in 0..num_frames {
for out_c in 0..out_len {
let mut sum = bias[out_c];
for in_c in 0..in_len {
sum += in_frames[n * in_len + in_c] * weights[in_c * out_len + out_c];
}
out_frames[n * out_len + out_c] = sum;
}
}
}
#[inline]
pub fn gemv_no_bias_f32_fallback(
in_frames: &[f32],
weights: &[f32],
out_frames: &mut [f32],
num_frames: usize,
) {
if num_frames == 0 {
return;
}
let in_len = in_frames.len() / num_frames;
let out_len = out_frames.len() / num_frames;
for n in 0..num_frames {
for out_c in 0..out_len {
let mut sum = 0.0;
for in_c in 0..in_len {
sum += in_frames[n * in_len + in_c] * weights[in_c * out_len + out_c];
}
out_frames[n * out_len + out_c] = sum;
}
}
}
#[inline]
pub fn fused_gemm_residual_batch_f32_fallback(
in_frames: &[f32],
weights: &[f32],
bias: &[f32],
residual: &[f32],
out_frames: &mut [f32],
num_frames: usize,
do_bias: bool,
) {
if num_frames == 0 {
return;
}
let in_len = in_frames.len() / num_frames;
let out_len = out_frames.len() / num_frames;
for frame_idx in 0..num_frames {
for out_c in 0..out_len {
let mut sum = residual[frame_idx * out_len + out_c];
if do_bias {
sum += bias[out_c];
}
for in_c in 0..in_len {
sum += in_frames[frame_idx * in_len + in_c] * weights[in_c * out_len + out_c];
}
out_frames[frame_idx * out_len + out_c] = sum;
}
}
}