Files
wifi-densepose/crates/ruvector-mincut-gated-transformer/benches/gate.rs
ruv d803bfe2b1 Squashed 'vendor/ruvector/' content from commit b64c2172
git-subtree-dir: vendor/ruvector
git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
2026-02-28 14:39:40 -05:00

270 lines
6.9 KiB
Rust

//! Gate overhead benchmarks.
//!
//! Measures the cost of gate evaluation separate from inference.
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
use ruvector_mincut_gated_transformer::{
gate::GateController, spike::SpikeScheduler, GatePacket, GatePolicy, SpikePacket,
};
fn bench_gate_evaluation(c: &mut Criterion) {
let mut group = c.benchmark_group("gate_evaluation");
let policy = GatePolicy::default();
let controller = GateController::new(policy);
// Allow case
let gate_allow = GatePacket {
lambda: 100,
lambda_prev: 95,
boundary_edges: 5,
boundary_concentration_q15: 8192,
partition_count: 3,
flags: 0,
};
group.bench_function("allow", |b| {
b.iter(|| {
let decision = controller.evaluate(black_box(&gate_allow), None);
black_box(decision)
})
});
// ReduceScope case
let gate_reduce = GatePacket {
lambda: 100,
lambda_prev: 95,
boundary_edges: 30, // Triggers boundary spike
boundary_concentration_q15: 8192,
partition_count: 3,
flags: 0,
};
group.bench_function("reduce_scope", |b| {
b.iter(|| {
let decision = controller.evaluate(black_box(&gate_reduce), None);
black_box(decision)
})
});
// FlushKv case
let gate_flush = GatePacket {
lambda: 30,
lambda_prev: 100, // 70% drop
boundary_edges: 5,
boundary_concentration_q15: 8192,
partition_count: 3,
flags: 0,
};
group.bench_function("flush_kv", |b| {
b.iter(|| {
let decision = controller.evaluate(black_box(&gate_flush), None);
black_box(decision)
})
});
// QuarantineUpdates case
let gate_quarantine = GatePacket {
lambda: 10, // Below min
lambda_prev: 100,
boundary_edges: 5,
boundary_concentration_q15: 8192,
partition_count: 3,
flags: 0,
};
group.bench_function("quarantine", |b| {
b.iter(|| {
let decision = controller.evaluate(black_box(&gate_quarantine), None);
black_box(decision)
})
});
group.finish();
}
fn bench_gate_with_spikes(c: &mut Criterion) {
let mut group = c.benchmark_group("gate_with_spikes");
let policy = GatePolicy::default();
let controller = GateController::new(policy);
let gate = GatePacket {
lambda: 100,
lambda_prev: 95,
boundary_edges: 5,
boundary_concentration_q15: 8192,
partition_count: 3,
flags: 0,
};
// Active spike
let spike_active = SpikePacket {
fired: 1,
rate_q15: 10000,
novelty_q15: 15000,
..Default::default()
};
group.bench_function("with_active_spike", |b| {
b.iter(|| {
let decision = controller.evaluate(black_box(&gate), Some(black_box(&spike_active)));
black_box(decision)
})
});
// Inactive spike
let spike_inactive = SpikePacket {
fired: 0,
..Default::default()
};
group.bench_function("with_inactive_spike", |b| {
b.iter(|| {
let decision = controller.evaluate(black_box(&gate), Some(black_box(&spike_inactive)));
black_box(decision)
})
});
// Storm spike
let spike_storm = SpikePacket {
fired: 1,
rate_q15: 30000, // Very high
novelty_q15: 5000,
..Default::default()
};
group.bench_function("with_storm_spike", |b| {
b.iter(|| {
let decision = controller.evaluate(black_box(&gate), Some(black_box(&spike_storm)));
black_box(decision)
})
});
group.finish();
}
fn bench_spike_scheduler(c: &mut Criterion) {
let mut group = c.benchmark_group("spike_scheduler");
let scheduler = SpikeScheduler::new();
// Active spike
let spike_active = SpikePacket {
fired: 1,
rate_q15: 10000,
novelty_q15: 15000,
top_len: 8,
top_idx: [1, 5, 10, 15, 20, 25, 30, 35, 0, 0, 0, 0, 0, 0, 0, 0],
top_w_q15: [
16384, 8192, 4096, 2048, 1024, 512, 256, 128, 0, 0, 0, 0, 0, 0, 0, 0,
],
flags: SpikePacket::FLAG_SPARSE_MASK,
};
group.bench_function("evaluate_active", |b| {
b.iter(|| {
let decision = scheduler.evaluate(black_box(&spike_active));
black_box(decision)
})
});
group.bench_function("build_sparse_mask", |b| {
b.iter(|| {
let mask = scheduler.build_sparse_mask(black_box(&spike_active), 64);
black_box(mask)
})
});
group.bench_function("get_weighted_positions", |b| {
b.iter(|| {
let positions = scheduler.get_weighted_positions(black_box(&spike_active));
black_box(positions)
})
});
group.finish();
}
fn bench_policy_variants(c: &mut Criterion) {
let mut group = c.benchmark_group("policy_variants");
let gate = GatePacket {
lambda: 50,
lambda_prev: 80,
boundary_edges: 15,
boundary_concentration_q15: 15000,
partition_count: 8,
flags: 0,
};
// Default policy
let default_controller = GateController::new(GatePolicy::default());
group.bench_function("default_policy", |b| {
b.iter(|| {
let decision = default_controller.evaluate(black_box(&gate), None);
black_box(decision)
})
});
// Conservative policy
let conservative_controller = GateController::new(GatePolicy::conservative());
group.bench_function("conservative_policy", |b| {
b.iter(|| {
let decision = conservative_controller.evaluate(black_box(&gate), None);
black_box(decision)
})
});
// Permissive policy
let permissive_controller = GateController::new(GatePolicy::permissive());
group.bench_function("permissive_policy", |b| {
b.iter(|| {
let decision = permissive_controller.evaluate(black_box(&gate), None);
black_box(decision)
})
});
group.finish();
}
fn bench_drop_ratio_calculation(c: &mut Criterion) {
let mut group = c.benchmark_group("drop_ratio");
for drop_percent in [10, 25, 50, 75].iter() {
let gate = GatePacket {
lambda: 100 - drop_percent,
lambda_prev: 100,
..Default::default()
};
group.bench_with_input(
BenchmarkId::from_parameter(drop_percent),
drop_percent,
|b, _| {
b.iter(|| {
let ratio = black_box(&gate).drop_ratio_q15();
black_box(ratio)
})
},
);
}
group.finish();
}
criterion_group!(
benches,
bench_gate_evaluation,
bench_gate_with_spikes,
bench_spike_scheduler,
bench_policy_variants,
bench_drop_ratio_calculation,
);
criterion_main!(benches);