mod activation;
mod attention;
mod fft;
mod layer;
mod matrix;
pub mod optimized;
#[cfg(test)]
mod property_tests;
pub mod vector;
pub use activation::{gelu, log_softmax, relu, sigmoid, softmax, tanh_activation};
pub use attention::{scaled_dot_product_attention, scaled_dot_product_attention_single};
pub use fft::{hann_window, multiply_accumulate};
pub use layer::{batch_layer_norm, layer_norm};
pub use matrix::{
enable_blis_profiling, matmul, matmul_owned, matmul_raw, matmul_with_matrix,
matmul_with_prepacked, matvec, take_blis_profiler, transpose,
};
pub use optimized::{
rms_norm, rms_norm_into, select_backend, tiled_matvec, tiled_matvec_f16, tiled_matvec_f16_into,
tiled_matvec_i4_into, tiled_matvec_i8_into, tiled_matvec_into, BackendCategory, GPU_THRESHOLD,
PARALLEL_THRESHOLD, TILE_SIZE,
};
pub use vector::{
add, add_inplace, argmax, axpy, broadcast_add_inplace, dequant_f16_row, dot, dot_f16, dot_i4,
dot_i8, dot_nalloc, dot_scalar, max, max_element, mean, min, mul, quant_f32_row_to_i4,
quant_f32_row_to_i8, quant_f32_to_f16, scale, scale_inplace, softmax_online_inplace, std_dev,
sub, sum, variance,
};
use trueno::Backend;
#[must_use]
pub fn best_backend() -> Backend {
trueno::select_best_available_backend()
}
#[must_use]
pub fn simd_available() -> bool {
!matches!(best_backend(), Backend::Scalar)
}
#[must_use]
pub fn backend_name() -> &'static str {
backend_name_for(best_backend())
}
#[must_use]
pub fn backend_name_for(backend: Backend) -> &'static str {
match backend {
Backend::Scalar => "Scalar",
Backend::SSE2 => "SSE2",
Backend::AVX => "AVX",
Backend::AVX2 => "AVX2",
Backend::AVX512 => "AVX512",
Backend::NEON => "NEON",
Backend::WasmSIMD => "WasmSIMD",
Backend::GPU => "GPU",
Backend::Auto => "Auto",
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_backend_available() {
let backend = best_backend();
let name = backend_name();
assert!(!name.is_empty());
println!("Backend: {name:?} = {backend:?}");
}
#[test]
fn test_simd_available() {
let _ = simd_available();
}
#[test]
fn test_backend_name_valid() {
let name = backend_name();
let valid_names = [
"Scalar", "SSE2", "AVX", "AVX2", "AVX512", "NEON", "WasmSIMD", "GPU", "Auto",
];
assert!(
valid_names.contains(&name),
"Backend name '{name}' not in valid list"
);
}
#[test]
fn test_best_backend_consistency() {
let b1 = best_backend();
let b2 = best_backend();
assert_eq!(b1, b2);
}
#[test]
fn test_simd_available_consistency() {
let a1 = simd_available();
let a2 = simd_available();
assert_eq!(a1, a2);
}
#[test]
fn test_re_exports() {
let _ = dot(&[1.0, 2.0], &[3.0, 4.0]);
let _ = softmax(&[1.0, 2.0, 3.0]);
let _ = gelu(&[0.0, 1.0]);
let _ = relu(&[-1.0, 0.0, 1.0]);
let _ = matmul(&[1.0, 0.0, 0.0, 1.0], &[1.0, 2.0, 3.0, 4.0], 2, 2, 2);
}
#[test]
fn test_backend_name_for_all_variants() {
assert_eq!(backend_name_for(Backend::Scalar), "Scalar");
assert_eq!(backend_name_for(Backend::SSE2), "SSE2");
assert_eq!(backend_name_for(Backend::AVX), "AVX");
assert_eq!(backend_name_for(Backend::AVX2), "AVX2");
assert_eq!(backend_name_for(Backend::AVX512), "AVX512");
assert_eq!(backend_name_for(Backend::NEON), "NEON");
assert_eq!(backend_name_for(Backend::WasmSIMD), "WasmSIMD");
assert_eq!(backend_name_for(Backend::GPU), "GPU");
assert_eq!(backend_name_for(Backend::Auto), "Auto");
}
}