use crate::common::enums::{DatabaseMode, FmhaQuantMode, KvCacheQuantMode};
use crate::common::error::AicError;
use crate::operators::base::{PerformanceResult, Source};
use crate::operators::util_empirical::{self, UtilGrid};
use crate::perf_database::attention::generation_attn_mode;
use crate::perf_database::gemm::quant_tc_flops;
use crate::perf_database::wideep_mla::{wideep_context_mla_sol_ms, wideep_generation_mla_sol_ms};
use crate::perf_database::PerfDatabase;
use serde::{Deserialize, Serialize};
fn prefix_correction(full_s: u32, prefix: u32) -> f64 {
if full_s == 0 {
return 0.0;
}
let f = full_s as f64;
let p = prefix as f64;
(f * f - p * p) / (f * f)
}
fn check_attn_backend(attn_backend: &str) -> Result<(), AicError> {
if attn_backend != "flashinfer" && attn_backend != "fa3" {
return Err(AicError::InvalidEngineConfig(format!(
"Unsupported attention backend: {attn_backend}"
)));
}
Ok(())
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct WideEpContextMlaOp {
pub name: String,
pub scale_factor: f64,
pub num_heads: u32,
pub kv_cache_dtype: KvCacheQuantMode,
pub fmha_quant_mode: FmhaQuantMode,
pub attn_backend: String,
#[serde(default = "crate::operators::gemm::default_seq_split")]
pub cp_size: u32,
}
impl WideEpContextMlaOp {
pub fn new(
name: impl Into<String>,
num_heads: u32,
kv_cache_dtype: KvCacheQuantMode,
fmha_quant_mode: FmhaQuantMode,
) -> Self {
Self {
name: name.into(),
scale_factor: 1.0,
num_heads,
kv_cache_dtype,
fmha_quant_mode,
attn_backend: "flashinfer".to_string(),
cp_size: 1,
}
}
pub fn query(
&self,
db: &PerfDatabase,
batch_size: u32,
isl: u32,
prefix: u32,
) -> Result<PerformanceResult, AicError> {
let ctx = |s: u32, pfx: u32| -> Result<(f64, Source), AicError> {
query_wideep_context_mla_table(
db,
batch_size,
s,
pfx,
self.num_heads,
self.kv_cache_dtype,
self.fmha_quant_mode,
&self.attn_backend,
)
};
let (latency, source) = if self.cp_size > 1 {
let c = isl.div_ceil(2 * self.cp_size).max(1);
let (first, first_source) = ctx(c, prefix)?;
let (second, second_source) = ctx(c, prefix + isl - c)?;
(first + second, first_source.combine(second_source))
} else {
ctx(isl, prefix)?
};
Ok(PerformanceResult::new(latency, source)
.clamp_non_negative()
.scaled(self.scale_factor))
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
fn h200_sglang_db() -> PerfDatabase {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("src/aiconfigurator_core/systems");
PerfDatabase::load(&root, "h200_sxm", "sglang", "0.5.10").expect("db loads")
}
fn op(cp_size: u32) -> WideEpContextMlaOp {
let mut op = WideEpContextMlaOp::new(
"wideep_ctx_mla",
128,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
);
op.attn_backend = "flashinfer".to_string();
op.cp_size = cp_size;
op
}
#[test]
fn cp_zigzag_composition() {
let db = h200_sglang_db();
let (b, isl, prefix) = (4u32, 4096u32, 0u32);
let baseline = op(1).query(&db, b, isl, prefix).expect("cp=1 query");
let raw = db
.wideep_mla
.query_context(
b,
isl + prefix,
128,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
"flashinfer",
)
.expect("raw table query");
assert!(
(baseline.latency_ms - raw).abs() < 1e-12,
"cp=1 must remain the plain query: {} vs {}",
baseline.latency_ms,
raw
);
let cp = 2u32;
let c = isl.div_ceil(2 * cp).max(1);
let chunked = op(cp).query(&db, b, isl, prefix).expect("cp=2 query");
let chunk1 = op(1).query(&db, b, c, prefix).expect("chunk1 query");
let chunk2 = op(1)
.query(&db, b, c, prefix + isl - c)
.expect("chunk2 query");
assert!(
(chunked.latency_ms - (chunk1.latency_ms + chunk2.latency_ms)).abs() < 1e-9,
"cp=2 ({}) must equal two-chunk sum ({} + {})",
chunked.latency_ms,
chunk1.latency_ms,
chunk2.latency_ms
);
assert!(
chunked.latency_ms > 0.0 && chunked.latency_ms < baseline.latency_ms,
"rank-0 CP work ({}) must be positive and below the full prefill ({})",
chunked.latency_ms,
baseline.latency_ms
);
}
fn assert_close(got: f64, expected: f64, what: &str) {
assert!(
(got - expected).abs() < 1e-9,
"{what}: expected {expected}, got {got}"
);
}
#[test]
fn wideep_context_mla_empirical_matches_python_oracles() {
let mut db = h200_sglang_db();
db.database_mode = crate::common::enums::DatabaseMode::Empirical;
let cases: &[(u32, u32, u32, u32, &str, f64)] = &[
(2, 3000, 1000, 16, "flashinfer", 0.7957964702937849),
(4, 4096, 0, 128, "flashinfer", 9.6274),
(4, 4096, 0, 128, "fa3", 9.7168),
];
for &(b, s, prefix, n, backend, expected) in cases {
let (latency, source) = query_wideep_context_mla_table(
&db,
b,
s,
prefix,
n,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
backend,
)
.expect("empirical query");
assert_close(
latency,
expected,
&format!("wideep_ctx_mla(b={b}, s={s}, pfx={prefix}, n={n}, {backend})"),
);
assert_eq!(source, Source::Empirical);
}
assert_eq!(
db.worst_provenance(),
util_empirical::ProvenanceTier::Empirical
);
db.database_mode = crate::common::enums::DatabaseMode::Hybrid;
let result = query_wideep_context_mla_table(
&db,
4,
4096,
0,
128,
KvCacheQuantMode::Bfloat16,
FmhaQuantMode::Fp8Block,
"flashinfer",
);
assert!(
matches!(result, Err(AicError::EmpiricalNotImplemented(_))),
"got {result:?}"
);
}
#[test]
fn wideep_generation_mla_empirical_matches_python_oracles() {
let mut db = h200_sglang_db();
db.database_mode = crate::common::enums::DatabaseMode::Empirical;
let cases: &[(u32, u32, u32, &str, f64)] = &[
(3, 5000, 16, "flashinfer", 0.0509930128230621),
(1, 4096, 128, "flashinfer", 0.1017),
(2, 9000, 128, "fa3", 0.12152241047815426),
];
for &(b, s, n, backend, expected) in cases {
let (latency, source) =
query_wideep_generation_mla_table(&db, b, s, n, KvCacheQuantMode::Fp8, backend)
.expect("empirical query");
assert_close(
latency,
expected,
&format!("wideep_gen_mla(b={b}, s={s}, n={n}, {backend})"),
);
assert_eq!(source, Source::Empirical);
}
assert_eq!(
db.worst_provenance(),
util_empirical::ProvenanceTier::Empirical
);
db.database_mode = crate::common::enums::DatabaseMode::Hybrid;
let result = query_wideep_generation_mla_table(
&db,
1,
4096,
128,
KvCacheQuantMode::Bfloat16,
"flashinfer",
);
assert!(
matches!(result, Err(AicError::EmpiricalNotImplemented(_))),
"got {result:?}"
);
}
#[test]
fn attn_backend_whitelist_mirrors_python() {
let db = h200_sglang_db();
let mut bad = op(1);
bad.attn_backend = "trtllm_mla".to_string();
let ctx = bad.query(&db, 1, 1024, 0);
assert!(
matches!(ctx, Err(AicError::InvalidEngineConfig(_))),
"context whitelist must reject trtllm_mla, got {ctx:?}"
);
let mut bad_gen = WideEpGenerationMlaOp::new(
"wideep_gen_mla",
128,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
);
bad_gen.attn_backend = "trtllm_mla".to_string();
let gen = bad_gen.query(&db, 1, 1024);
assert!(
matches!(gen, Err(AicError::InvalidEngineConfig(_))),
"generation whitelist must reject trtllm_mla, got {gen:?}"
);
let mut fa3 = op(1);
fa3.attn_backend = "fa3".to_string();
assert!(fa3.query(&db, 1, 1024, 0).is_ok());
let mut hybrid = h200_sglang_db();
hybrid.database_mode = crate::common::enums::DatabaseMode::Hybrid;
let mut bad = op(1);
bad.attn_backend = "trtllm_mla".to_string();
let result = bad.query(&hybrid, 1, 1024, 0);
assert!(
matches!(result, Err(AicError::InvalidEngineConfig(_))),
"HYBRID must propagate the whitelist error, got {result:?}"
);
}
#[test]
fn empirical_resolves_user_backends_and_exact_kernel_sources() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("src/aiconfigurator_core/systems");
let mut db = PerfDatabase::load(&root, "b200_sxm", "sglang", "0.5.10").expect("db loads");
db.database_mode = crate::common::enums::DatabaseMode::Empirical;
let ctx_cases: &[(u32, u32, u32, u32, f64)] = &[
(4, 4096, 0, 128, 5.1478),
(2, 3000, 1000, 16, 0.5668068670651026),
];
for backend in ["trtllm_mla", "flashinfer", "fa3"] {
for &(b, s, prefix, n, expected) in ctx_cases {
let (latency, source) = query_wideep_context_mla_table(
&db,
b,
s,
prefix,
n,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
backend,
)
.expect("supported backend resolves to the trtllm_mla slice");
assert_close(
latency,
expected,
&format!("{backend} ctx(b={b}, s={s}, pfx={prefix})"),
);
assert_eq!(source, Source::Empirical);
}
let (latency, source) =
query_wideep_generation_mla_table(&db, 3, 5000, 16, KvCacheQuantMode::Fp8, backend)
.expect("supported backend resolves to the trtllm_mla slice");
assert_close(
latency,
0.056915046282426024,
&format!("{backend} gen(b=3, s=5000)"),
);
assert_eq!(source, Source::Empirical);
}
for invalid in ["", "torch"] {
let context = query_wideep_context_mla_table(
&db,
1,
1024,
0,
128,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
invalid,
);
assert!(
matches!(context, Err(AicError::InvalidEngineConfig(_))),
"invalid backend {invalid:?} must not borrow trtllm_mla, got {context:?}"
);
let generation = query_wideep_generation_mla_table(
&db,
1,
1024,
128,
KvCacheQuantMode::Fp8,
invalid,
);
assert!(
matches!(generation, Err(AicError::InvalidEngineConfig(_))),
"invalid backend {invalid:?} must not borrow trtllm_mla, got {generation:?}"
);
}
}
#[test]
fn hybrid_unloaded_table_falls_to_empirical_before_whitelist() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("src/aiconfigurator_core/systems");
let mut db = PerfDatabase::load(&root, "b200_sxm", "vllm", "0.19.0").expect("db loads");
db.database_mode = crate::common::enums::DatabaseMode::Hybrid;
let result = query_wideep_context_mla_table(
&db,
1,
1024,
0,
128,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
"trtllm_mla",
);
assert!(
matches!(result, Err(AicError::EmpiricalNotImplemented(_))),
"expected the typed empirical miss, got {result:?}"
);
}
#[test]
fn wideep_mla_sol_mode_returns_roofline_with_sol_source() {
let mut db = h200_sglang_db();
db.database_mode = DatabaseMode::Sol;
let spec = db.system_spec.clone();
let mut ctx = op(1);
ctx.attn_backend = "not_a_backend".to_string();
let result = ctx.query(&db, 2, 4096, 512).expect("wideep ctx sol");
let main_flops = quant_tc_flops(&spec, ctx.fmha_quant_mode.mapping()).unwrap();
let bf16_flops = quant_tc_flops(&spec, FmhaQuantMode::Bfloat16.mapping()).unwrap();
let expected = wideep_context_mla_sol_ms(
&spec,
ctx.fmha_quant_mode,
ctx.num_heads as f64,
4096.0,
512.0,
2.0,
main_flops,
bf16_flops,
);
assert_eq!(result.latency_ms, expected);
assert_eq!(result.source, Source::Sol);
assert_eq!(result.energy_wms, 0.0);
let mut gen = WideEpGenerationMlaOp::new(
"wideep_gen_mla",
16,
KvCacheQuantMode::Fp8,
FmhaQuantMode::Fp8Block,
);
gen.attn_backend = "flashinfer".to_string();
let result = gen.query(&db, 8, 4096).expect("wideep gen sol");
let fmha = generation_attn_mode(&spec, KvCacheQuantMode::Fp8);
let main_flops = quant_tc_flops(&spec, fmha.mapping()).unwrap();
let expected =
wideep_generation_mla_sol_ms(&spec, fmha, 16.0, 8.0, 4096.0, main_flops, bf16_flops);
assert_eq!(result.latency_ms, expected);
assert_eq!(result.source, Source::Sol);
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct WideEpGenerationMlaOp {
pub name: String,
pub scale_factor: f64,
pub num_heads: u32,
pub kv_cache_dtype: KvCacheQuantMode,
pub fmha_quant_mode: FmhaQuantMode,
pub attn_backend: String,
}
impl WideEpGenerationMlaOp {
pub fn new(
name: impl Into<String>,
num_heads: u32,
kv_cache_dtype: KvCacheQuantMode,
fmha_quant_mode: FmhaQuantMode,
) -> Self {
Self {
name: name.into(),
scale_factor: 1.0,
num_heads,
kv_cache_dtype,
fmha_quant_mode,
attn_backend: "flashinfer".to_string(),
}
}
pub fn query(
&self,
db: &PerfDatabase,
batch_size: u32,
s: u32,
) -> Result<PerformanceResult, AicError> {
let (latency, source) = query_wideep_generation_mla_table(
db,
batch_size,
s,
self.num_heads,
self.kv_cache_dtype,
&self.attn_backend,
)?;
Ok(PerformanceResult::new(latency, source)
.clamp_non_negative()
.scaled(self.scale_factor))
}
}
fn wideep_sample_num_head(n: f64) -> f64 {
let tp_size = (128.0 / n).round_ties_even();
(128.0 / tp_size).floor()
}
#[allow(clippy::too_many_arguments)]
fn query_wideep_context_mla_table(
db: &PerfDatabase,
b: u32,
s: u32,
prefix: u32,
num_heads: u32,
kv_quant: KvCacheQuantMode,
fmha_quant: FmhaQuantMode,
attn_backend: &str,
) -> Result<(f64, Source), AicError> {
let silicon = || -> Result<f64, AicError> {
db.wideep_mla.ensure_context_loaded()?;
check_attn_backend(attn_backend)?;
let full_s = s + prefix;
let raw = db.wideep_mla.query_context(
b,
full_s,
num_heads,
kv_quant,
fmha_quant,
attn_backend,
)?;
Ok(raw * prefix_correction(full_s, prefix))
};
match db.database_mode {
DatabaseMode::Sol | DatabaseMode::SolFull => {
let spec = &db.system_spec;
let main_flops = quant_tc_flops(spec, fmha_quant.mapping())?;
let bf16_flops = quant_tc_flops(spec, FmhaQuantMode::Bfloat16.mapping())?;
Ok((
wideep_context_mla_sol_ms(
spec,
fmha_quant,
num_heads as f64,
s as f64,
prefix as f64,
b as f64,
main_flops,
bf16_flops,
),
Source::Sol,
))
}
DatabaseMode::Empirical => Ok((
wideep_context_mla_empirical(
db,
b,
s,
prefix,
num_heads,
kv_quant,
fmha_quant,
attn_backend,
)?,
Source::Empirical,
)),
DatabaseMode::Hybrid => match silicon() {
Ok(latency) => Ok((latency, Source::Silicon)),
Err(err) if err.is_missing_perf_data() => Ok((
wideep_context_mla_empirical(
db,
b,
s,
prefix,
num_heads,
kv_quant,
fmha_quant,
attn_backend,
)?,
Source::Empirical,
)),
Err(err) => Err(err),
},
_ => Ok((silicon()?, Source::Silicon)),
}
}
#[allow(clippy::too_many_arguments)]
fn wideep_context_mla_empirical(
db: &PerfDatabase,
b: u32,
s: u32,
prefix: u32,
num_heads: u32,
kv_quant: KvCacheQuantMode,
fmha_quant: FmhaQuantMode,
attn_backend: &str,
) -> Result<f64, AicError> {
let spec = &db.system_spec;
let main_flops = quant_tc_flops(spec, fmha_quant.mapping())?;
let bf16_flops = quant_tc_flops(spec, FmhaQuantMode::Bfloat16.mapping())?;
let sol = |c: &[f64]| {
wideep_context_mla_sol_ms(
spec,
fmha_quant,
wideep_sample_num_head(c[0]),
c[1],
0.0,
c[2],
main_flops,
bf16_flops,
)
};
let key = format!(
"wideep_ctx_mla:{attn_backend}:{}:{}",
fmha_quant.name(),
kv_quant.name()
);
let grid = db.util_grids.get_or_try_build(&key, || {
match db
.wideep_mla
.context_points(attn_backend, kv_quant, fmha_quant)
{
Ok(points) => Ok(Some(UtilGrid::new(util_empirical::build_samples(
points, sol,
)))),
Err(err) if err.is_missing_perf_data() => Ok(None),
Err(err) => Err(err),
}
})?;
let sol_query = wideep_context_mla_sol_ms(
spec,
fmha_quant,
num_heads as f64,
s as f64,
prefix as f64,
b as f64,
main_flops,
bf16_flops,
);
let query = [num_heads as f64, (s + prefix) as f64, b as f64];
let (latency, _) = util_empirical::estimate(sol_query, &query, grid.as_deref(), 1.0)?;
db.note_provenance(util_empirical::ProvenanceTier::Empirical);
Ok(latency)
}
fn query_wideep_generation_mla_table(
db: &PerfDatabase,
b: u32,
s: u32,
num_heads: u32,
kv_quant: KvCacheQuantMode,
attn_backend: &str,
) -> Result<(f64, Source), AicError> {
let silicon = || -> Result<f64, AicError> {
db.wideep_mla.ensure_generation_loaded()?;
check_attn_backend(attn_backend)?;
db.wideep_mla
.query_generation(b, s, num_heads, kv_quant, attn_backend)
};
match db.database_mode {
DatabaseMode::Sol | DatabaseMode::SolFull => {
let spec = &db.system_spec;
let fmha_quant = generation_attn_mode(spec, kv_quant);
let main_flops = quant_tc_flops(spec, fmha_quant.mapping())?;
let bf16_flops = quant_tc_flops(spec, FmhaQuantMode::Bfloat16.mapping())?;
Ok((
wideep_generation_mla_sol_ms(
spec,
fmha_quant,
num_heads as f64,
b as f64,
s as f64,
main_flops,
bf16_flops,
),
Source::Sol,
))
}
DatabaseMode::Empirical => Ok((
wideep_generation_mla_empirical(db, b, s, num_heads, kv_quant, attn_backend)?,
Source::Empirical,
)),
DatabaseMode::Hybrid => match silicon() {
Ok(latency) => Ok((latency, Source::Silicon)),
Err(err) if err.is_missing_perf_data() => Ok((
wideep_generation_mla_empirical(db, b, s, num_heads, kv_quant, attn_backend)?,
Source::Empirical,
)),
Err(err) => Err(err),
},
_ => Ok((silicon()?, Source::Silicon)),
}
}
fn wideep_generation_mla_empirical(
db: &PerfDatabase,
b: u32,
s: u32,
num_heads: u32,
kv_quant: KvCacheQuantMode,
attn_backend: &str,
) -> Result<f64, AicError> {
let spec = &db.system_spec;
let fmha_quant = generation_attn_mode(spec, kv_quant);
let main_flops = quant_tc_flops(spec, fmha_quant.mapping())?;
let bf16_flops = quant_tc_flops(spec, FmhaQuantMode::Bfloat16.mapping())?;
let sol = |c: &[f64]| {
wideep_generation_mla_sol_ms(
spec,
fmha_quant,
wideep_sample_num_head(c[0]),
c[1],
c[2],
main_flops,
bf16_flops,
)
};
let key = format!("wideep_gen_mla:{attn_backend}:{}", kv_quant.name());
let grid = db.util_grids.get_or_try_build(&key, || {
match db.wideep_mla.generation_points(attn_backend, kv_quant) {
Ok(points) => Ok(Some(UtilGrid::new(util_empirical::build_samples(
points, sol,
)))),
Err(err) if err.is_missing_perf_data() => Ok(None),
Err(err) => Err(err),
}
})?;
let sol_query = wideep_generation_mla_sol_ms(
spec,
fmha_quant,
num_heads as f64,
b as f64,
s as f64,
main_flops,
bf16_flops,
);
let query = [num_heads as f64, b as f64, s as f64];
let (latency, _) = util_empirical::estimate(sol_query, &query, grid.as_deref(), 1.0)?;
db.note_provenance(util_empirical::ProvenanceTier::Empirical);
Ok(latency)
}