Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
339
vendor/ruvector/crates/cognitum-gate-tilezero/benches/decision_bench.rs
vendored
Normal file
339
vendor/ruvector/crates/cognitum-gate-tilezero/benches/decision_bench.rs
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
//! Benchmarks for the full decision pipeline
|
||||
//!
|
||||
//! Target latencies:
|
||||
//! - Gate decision: p99 < 50ms
|
||||
//! - E-value computation: < 1ms
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use cognitum_gate_tilezero::{
|
||||
ActionContext, ActionMetadata, ActionTarget, DecisionOutcome, EvidenceFilter, GateThresholds,
|
||||
ReducedGraph, ThreeFilterDecision, TileZero,
|
||||
};
|
||||
|
||||
/// Create a realistic action context for benchmarking
|
||||
fn create_action_context(id: usize) -> ActionContext {
|
||||
ActionContext {
|
||||
action_id: format!("action-{}", id),
|
||||
action_type: "config_change".to_string(),
|
||||
target: ActionTarget {
|
||||
device: Some("router-1".to_string()),
|
||||
path: Some("/config/routing/policy".to_string()),
|
||||
extra: {
|
||||
let mut m = HashMap::new();
|
||||
m.insert("priority".to_string(), serde_json::json!(100));
|
||||
m.insert("region".to_string(), serde_json::json!("us-west-2"));
|
||||
m
|
||||
},
|
||||
},
|
||||
context: ActionMetadata {
|
||||
agent_id: "agent-001".to_string(),
|
||||
session_id: Some("session-12345".to_string()),
|
||||
prior_actions: vec!["action-prev-1".to_string(), "action-prev-2".to_string()],
|
||||
urgency: "normal".to_string(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a graph with realistic state
|
||||
fn create_realistic_graph(coherence_level: f64) -> ReducedGraph {
|
||||
let mut graph = ReducedGraph::new();
|
||||
|
||||
// Simulate 255 worker tiles reporting
|
||||
for tile_id in 1..=255u8 {
|
||||
// Vary coherence slightly around the target
|
||||
let tile_coherence = (coherence_level + (tile_id as f64 * 0.001) % 0.1) as f32;
|
||||
graph.update_coherence(tile_id, tile_coherence);
|
||||
}
|
||||
|
||||
// Set realistic values
|
||||
graph.set_global_cut(coherence_level * 15.0);
|
||||
graph.set_evidence(coherence_level * 150.0);
|
||||
graph.set_shift_pressure(0.1 * (1.0 - coherence_level));
|
||||
|
||||
graph
|
||||
}
|
||||
|
||||
/// Benchmark the full TileZero decision pipeline
|
||||
fn bench_full_decision_pipeline(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
let mut group = c.benchmark_group("decision_pipeline");
|
||||
group.throughput(Throughput::Elements(1));
|
||||
|
||||
// Benchmark with different threshold configurations
|
||||
let thresholds_configs = vec![
|
||||
("default", GateThresholds::default()),
|
||||
(
|
||||
"strict",
|
||||
GateThresholds {
|
||||
tau_deny: 0.001,
|
||||
tau_permit: 200.0,
|
||||
min_cut: 10.0,
|
||||
max_shift: 0.3,
|
||||
permit_ttl_ns: 30_000_000_000,
|
||||
theta_uncertainty: 30.0,
|
||||
theta_confidence: 3.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
"relaxed",
|
||||
GateThresholds {
|
||||
tau_deny: 0.1,
|
||||
tau_permit: 50.0,
|
||||
min_cut: 2.0,
|
||||
max_shift: 0.8,
|
||||
permit_ttl_ns: 120_000_000_000,
|
||||
theta_uncertainty: 10.0,
|
||||
theta_confidence: 10.0,
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
for (name, thresholds) in thresholds_configs {
|
||||
let tilezero = TileZero::new(thresholds);
|
||||
let ctx = create_action_context(0);
|
||||
|
||||
group.bench_with_input(BenchmarkId::new("tilezero_decide", name), &ctx, |b, ctx| {
|
||||
b.to_async(&rt)
|
||||
.iter(|| async { black_box(tilezero.decide(black_box(ctx)).await) });
|
||||
});
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark the three-filter decision logic
|
||||
fn bench_three_filter_decision(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("three_filter_decision");
|
||||
group.throughput(Throughput::Elements(1));
|
||||
|
||||
let thresholds = GateThresholds::default();
|
||||
let decision = ThreeFilterDecision::new(thresholds);
|
||||
|
||||
// Test different graph states
|
||||
let graph_states = vec![
|
||||
("high_coherence", create_realistic_graph(0.95)),
|
||||
("medium_coherence", create_realistic_graph(0.7)),
|
||||
("low_coherence", create_realistic_graph(0.3)),
|
||||
];
|
||||
|
||||
for (name, graph) in graph_states {
|
||||
group.bench_with_input(BenchmarkId::new("evaluate", name), &graph, |b, graph| {
|
||||
b.iter(|| black_box(decision.evaluate(black_box(graph))))
|
||||
});
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark E-value computation (scalar)
|
||||
fn bench_e_value_scalar(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("e_value_computation");
|
||||
group.throughput(Throughput::Elements(1));
|
||||
|
||||
// Test different filter capacities
|
||||
for capacity in [10, 100, 1000] {
|
||||
let mut filter = EvidenceFilter::new(capacity);
|
||||
|
||||
// Pre-fill the filter
|
||||
for i in 0..capacity {
|
||||
filter.update(1.0 + (i as f64 * 0.001));
|
||||
}
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("scalar_update", capacity),
|
||||
&capacity,
|
||||
|b, _| {
|
||||
b.iter(|| {
|
||||
filter.update(black_box(1.5));
|
||||
black_box(filter.current())
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark E-value computation with SIMD-friendly patterns
|
||||
fn bench_e_value_simd(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("e_value_simd");
|
||||
|
||||
// Simulate SIMD batch processing of 255 tile e-values
|
||||
let tile_count = 255;
|
||||
group.throughput(Throughput::Elements(tile_count as u64));
|
||||
|
||||
// Generate test data aligned for SIMD
|
||||
let e_values: Vec<f64> = (0..tile_count).map(|i| 1.0 + (i as f64 * 0.01)).collect();
|
||||
|
||||
// Scalar baseline
|
||||
group.bench_function("aggregate_scalar", |b| {
|
||||
b.iter(|| {
|
||||
let product: f64 = e_values.iter().product();
|
||||
black_box(product)
|
||||
})
|
||||
});
|
||||
|
||||
// Chunked processing (SIMD-friendly)
|
||||
group.bench_function("aggregate_chunked_4", |b| {
|
||||
b.iter(|| {
|
||||
let mut accumulator = 1.0f64;
|
||||
for chunk in e_values.chunks(4) {
|
||||
let chunk_product: f64 = chunk.iter().product();
|
||||
accumulator *= chunk_product;
|
||||
}
|
||||
black_box(accumulator)
|
||||
})
|
||||
});
|
||||
|
||||
// Parallel reduction pattern
|
||||
group.bench_function("aggregate_parallel_reduction", |b| {
|
||||
b.iter(|| {
|
||||
// Split into 8 lanes for potential SIMD
|
||||
let mut lanes = [1.0f64; 8];
|
||||
for (i, &val) in e_values.iter().enumerate() {
|
||||
lanes[i % 8] *= val;
|
||||
}
|
||||
let result: f64 = lanes.iter().product();
|
||||
black_box(result)
|
||||
})
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark decision outcome creation
|
||||
fn bench_decision_outcome(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("decision_outcome");
|
||||
group.throughput(Throughput::Elements(1));
|
||||
|
||||
group.bench_function("create_permit", |b| {
|
||||
b.iter(|| {
|
||||
black_box(DecisionOutcome::permit(
|
||||
black_box(0.95),
|
||||
black_box(1.0),
|
||||
black_box(0.9),
|
||||
black_box(0.95),
|
||||
black_box(10.0),
|
||||
))
|
||||
})
|
||||
});
|
||||
|
||||
group.bench_function("create_deny", |b| {
|
||||
b.iter(|| {
|
||||
black_box(DecisionOutcome::deny(
|
||||
cognitum_gate_tilezero::DecisionFilter::Structural,
|
||||
"Low coherence".to_string(),
|
||||
black_box(0.3),
|
||||
black_box(0.5),
|
||||
black_box(0.2),
|
||||
black_box(2.0),
|
||||
))
|
||||
})
|
||||
});
|
||||
|
||||
group.bench_function("create_defer", |b| {
|
||||
b.iter(|| {
|
||||
black_box(DecisionOutcome::defer(
|
||||
cognitum_gate_tilezero::DecisionFilter::Shift,
|
||||
"High shift pressure".to_string(),
|
||||
black_box(0.8),
|
||||
black_box(0.3),
|
||||
black_box(0.7),
|
||||
black_box(6.0),
|
||||
))
|
||||
})
|
||||
});
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark witness summary generation
|
||||
fn bench_witness_summary(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("witness_summary");
|
||||
group.throughput(Throughput::Elements(1));
|
||||
|
||||
let graph = create_realistic_graph(0.9);
|
||||
|
||||
group.bench_function("generate", |b| {
|
||||
b.iter(|| black_box(graph.witness_summary()))
|
||||
});
|
||||
|
||||
let summary = graph.witness_summary();
|
||||
group.bench_function("hash", |b| b.iter(|| black_box(summary.hash())));
|
||||
|
||||
group.bench_function("to_json", |b| b.iter(|| black_box(summary.to_json())));
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark batch decision processing
|
||||
fn bench_batch_decisions(c: &mut Criterion) {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
let mut group = c.benchmark_group("batch_decisions");
|
||||
|
||||
for batch_size in [10, 50, 100] {
|
||||
group.throughput(Throughput::Elements(batch_size as u64));
|
||||
|
||||
let thresholds = GateThresholds::default();
|
||||
let tilezero = TileZero::new(thresholds);
|
||||
|
||||
let contexts: Vec<_> = (0..batch_size).map(create_action_context).collect();
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("sequential", batch_size),
|
||||
&contexts,
|
||||
|b, contexts| {
|
||||
b.to_async(&rt).iter(|| async {
|
||||
for ctx in contexts {
|
||||
black_box(tilezero.decide(ctx).await);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
/// Benchmark graph updates from tile reports
|
||||
fn bench_graph_updates(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("graph_updates");
|
||||
|
||||
for tile_count in [64, 128, 255] {
|
||||
group.throughput(Throughput::Elements(tile_count as u64));
|
||||
|
||||
group.bench_with_input(
|
||||
BenchmarkId::new("coherence_updates", tile_count),
|
||||
&tile_count,
|
||||
|b, &count| {
|
||||
b.iter(|| {
|
||||
let mut graph = ReducedGraph::new();
|
||||
for tile_id in 1..=count as u8 {
|
||||
graph.update_coherence(tile_id, black_box(0.9));
|
||||
}
|
||||
black_box(graph)
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
bench_full_decision_pipeline,
|
||||
bench_three_filter_decision,
|
||||
bench_e_value_scalar,
|
||||
bench_e_value_simd,
|
||||
bench_decision_outcome,
|
||||
bench_witness_summary,
|
||||
bench_batch_decisions,
|
||||
bench_graph_updates,
|
||||
);
|
||||
|
||||
criterion_main!(benches);
|
||||
Reference in New Issue
Block a user