use batuta::backend::{BackendSelector, OpComplexity};
fn main() {
println!("šÆ Mixture-of-Experts Backend Routing Demo");
println!("==========================================\n");
let selector = BackendSelector::new();
println!("š Low Complexity (Element-wise operations)");
println!("-------------------------------------------");
let sizes = vec![100, 10_000, 500_000, 2_000_000];
for size in sizes {
let backend = selector.select_with_moe(OpComplexity::Low, size);
println!(
" {} elements: {} ({})",
format_size(size),
backend,
explain_low_complexity(size)
);
}
println!();
println!("š Medium Complexity (Reductions: dot, sum)");
println!("--------------------------------------------");
let sizes = vec![1_000, 50_000, 150_000, 500_000];
for size in sizes {
let backend = selector.select_with_moe(OpComplexity::Medium, size);
println!(
" {} elements: {} ({})",
format_size(size),
backend,
explain_medium_complexity(size)
);
}
println!();
println!("š High Complexity (Matrix operations)");
println!("---------------------------------------");
let sizes = vec![500, 5_000, 50_000, 200_000];
for size in sizes {
let backend = selector.select_with_moe(OpComplexity::High, size);
println!(
" {} elements: {} ({})",
format_size(size),
backend,
explain_high_complexity(size)
);
}
println!();
println!("š” Practical Examples");
println!("---------------------");
let pixels = 1920 * 1080; let backend = selector.select_with_moe(OpComplexity::Low, pixels);
println!(" Full HD image ({}px): {}", format_size(pixels), backend);
let embedding_dim = 768 * 1000; let backend = selector.select_with_moe(OpComplexity::Medium, embedding_dim);
println!(" ML embedding dot product ({}): {}", format_size(embedding_dim), backend);
let matrix_size = 512 * 512; let backend = selector.select_with_moe(OpComplexity::High, matrix_size);
println!(" 512Ć512 matrix multiply ({}): {}", format_size(matrix_size), backend);
println!("\nš Performance Insights");
println!("-----------------------");
println!(" ⢠Low complexity: GPU rarely beneficial (memory-bound)");
println!(" ⢠Medium complexity: GPU at 100K+ elements");
println!(" ⢠High complexity: GPU at 10K+ elements (O(n²) or O(n³))");
println!("\n Threshold values based on Trueno performance analysis");
println!(" and the 5Ć PCIe dispatch rule (Gregg & Hazelwood 2011)");
}
fn format_size(n: usize) -> String {
if n >= 1_000_000 {
format!("{:.1}M", n as f64 / 1_000_000.0)
} else if n >= 1_000 {
format!("{:.0}K", n as f64 / 1_000.0)
} else {
n.to_string()
}
}
fn explain_low_complexity(size: usize) -> &'static str {
if size > 1_000_000 {
"SIMD for large arrays"
} else {
"Scalar, memory-bound"
}
}
fn explain_medium_complexity(size: usize) -> &'static str {
if size > 100_000 {
"GPU worthwhile"
} else if size > 10_000 {
"SIMD optimal"
} else {
"Scalar sufficient"
}
}
fn explain_high_complexity(size: usize) -> &'static str {
if size > 10_000 {
"GPU beneficial for O(n²/n³)"
} else if size > 1_000 {
"SIMD for medium matrices"
} else {
"Scalar for small ops"
}
}