use inferencelayer::deepencoder_gpu::bench_sam_attention;
use inferencelayer::GpuCtx;
fn main() -> anyhow::Result<()> {
let ctx = GpuCtx::new()?;
println!("backend: {}", ctx.backend);
println!(
"caps: subgroups={} coop_matrix={} f16={}",
ctx.subgroups, ctx.coop_matrix, ctx.f16
);
if let Ok(dir) = std::env::var("GLM_DIR") {
use inferencelayer::vision::ImagePatches;
let cpu = inferencelayer::vision_glm::GlmVisionTower::load(std::path::Path::new(&dir))?;
let pd = cpu.cfg.patch_dim();
let fill = |len: usize| -> Vec<f32> {
let mut s = 7u32;
(0..len)
.map(|_| {
s = s.wrapping_mul(1664525).wrapping_add(1013904223);
((s >> 8) as f32 / 16_777_216.0 - 0.5) * 0.2
})
.collect()
};
for (bm, bn, bk) in [(128usize,128usize,16usize),(128,128,32),(64,128,16),(128,64,16),(64,64,16)] {
let gpu = inferencelayer::vision_glm_gpu::GlmVisionGpu::new_full(&ctx, &cpu, 16, true, bm, bn, bk)?;
for (label, gh, gw) in [("~760x980", 54u32, 70u32), ("~1240x1600", 88u32, 114u32)] {
let n = (gh * gw) as usize;
let img = ImagePatches { patches: fill(n * pd), grid: [1, gh, gw] };
let _ = gpu.forward(&ctx, &[img.clone()])?;
let t = std::time::Instant::now();
for _ in 0..3 { let _ = gpu.forward(&ctx, &[img.clone()])?; }
let ms = t.elapsed().as_secs_f64() * 1000.0 / 3.0;
println!("GLM tower tile={bm}x{bn}x{bk} {label}: {ms:.0} ms");
}
}
if std::env::var("GLM_RB_SWEEP").is_err() { return Ok(()); }
for rb in [4usize, 8, 16, 32] {
let gpu = inferencelayer::vision_glm_gpu::GlmVisionGpu::new_with_rb(&ctx, &cpu, rb)?;
for (label, gh, gw) in [("~760x980", 54u32, 70u32), ("~1240x1600", 88u32, 114u32)] {
let n = (gh * gw) as usize;
let img = ImagePatches {
patches: fill(n * pd),
grid: [1, gh, gw],
};
let _ = gpu.forward(&ctx, &[img.clone()])?; let t = std::time::Instant::now();
let iters = 3;
for _ in 0..iters {
let _ = gpu.forward(&ctx, &[img.clone()])?;
}
let ms = t.elapsed().as_secs_f64() * 1000.0 / iters as f64;
println!("GLM tower rb={rb:<2} {label} ({n} patches): {ms:.0} ms");
}
}
return Ok(());
}
let (gh, gw, width, heads, iters) = (64usize, 64usize, 768usize, 12usize, 5usize);
let (naive, flash) = bench_sam_attention(&ctx, gh, gw, width, heads, iters);
let n = gh * gw;
println!("=== SAM global attention ({}²,{}d,{}h) on this adapter ===", gh, width, heads);
println!(" naive-dense (805MB n² buffer, 3 passes): {:8.2} ms", naive);
println!(" register-flash (no n² buffer, portable): {:8.2} ms", flash);
println!(" SPEEDUP: {:.2}× (naive n² buffer = {:.0} MB)", naive / flash, (heads * n * n * 4) as f64 / 1.0e6);
Ok(())
}