style: apply rustfmt across entire codebase

Run rustfmt on all Rust files to fix CI formatting checks.
This addresses pre-existing formatting inconsistencies across:
- cognitum-gate-kernel
- cognitum-gate-tilezero
- prime-radiant
- ruvector-* crates
- examples/benchmarks
- and other crates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rUv 2026-01-28 17:00:26 +00:00
parent 859f93e916
commit 42d869a196
645 changed files with 17864 additions and 11023 deletions

View file

@ -13,7 +13,9 @@ use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criteri
use cognitum_gate_kernel::{
delta::{Delta, Observation},
evidence::{EvidenceAccumulator, HypothesisState, LogEValue, f32_to_log_e, LOG_LR_CONNECTIVITY_POS},
evidence::{
f32_to_log_e, EvidenceAccumulator, HypothesisState, LogEValue, LOG_LR_CONNECTIVITY_POS,
},
report::TileReport,
shard::{CompactGraph, MAX_SHARD_VERTICES},
TileState, MAX_DELTA_BUFFER,
@ -400,8 +402,8 @@ fn bench_mixture_evalue(c: &mut Criterion) {
// Scalar baseline
group.bench_function("aggregate_16_scalar", |b| {
let log_e_values: [LogEValue; 16] = [
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768,
65536, 65536, 38550, -65536, 65536, 38550, 65536, 38550,
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768, 65536, 65536, 38550, -65536,
65536, 38550, 65536, 38550,
];
b.iter(|| {
@ -413,8 +415,8 @@ fn bench_mixture_evalue(c: &mut Criterion) {
// Parallel lanes pattern (SIMD-friendly)
group.bench_function("aggregate_16_parallel_lanes", |b| {
let log_e_values: [LogEValue; 16] = [
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768,
65536, 65536, 38550, -65536, 65536, 38550, 65536, 38550,
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768, 65536, 65536, 38550, -65536,
65536, 38550, 65536, 38550,
];
b.iter(|| {
@ -431,8 +433,8 @@ fn bench_mixture_evalue(c: &mut Criterion) {
// Chunked processing (auto-vectorization friendly)
group.bench_function("aggregate_16_chunked", |b| {
let log_e_values: [LogEValue; 16] = [
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768,
65536, 65536, 38550, -65536, 65536, 38550, 65536, 38550,
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768, 65536, 65536, 38550, -65536,
65536, 38550, 65536, 38550,
];
b.iter(|| {
@ -460,8 +462,8 @@ fn bench_mixture_evalue(c: &mut Criterion) {
// Mixture with product (exp-log pattern)
group.bench_function("mixture_product_16", |b| {
let log_e_values: [LogEValue; 16] = [
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768,
65536, 65536, 38550, -65536, 65536, 38550, 65536, 38550,
65536, 38550, -65536, 65536, 38550, 65536, 38550, -32768, 65536, 65536, 38550, -65536,
65536, 38550, 65536, 38550,
];
b.iter(|| {
@ -628,23 +630,11 @@ fn bench_memory_patterns(c: &mut Criterion) {
// Criterion Groups
// ============================================================================
criterion_group!(
edge_benches,
bench_edge_insert,
bench_edge_batch,
);
criterion_group!(edge_benches, bench_edge_insert, bench_edge_batch,);
criterion_group!(
tick_benches,
bench_tick,
bench_tick_under_load,
);
criterion_group!(tick_benches, bench_tick, bench_tick_under_load,);
criterion_group!(
evidence_benches,
bench_evalue_update,
bench_mixture_evalue,
);
criterion_group!(evidence_benches, bench_evalue_update, bench_mixture_evalue,);
criterion_group!(
misc_benches,

View file

@ -404,7 +404,10 @@ impl Delta {
// Compile-time size assertions
const _: () = assert!(size_of::<EdgeAdd>() == 8, "EdgeAdd must be 8 bytes");
const _: () = assert!(size_of::<EdgeRemove>() == 8, "EdgeRemove must be 8 bytes");
const _: () = assert!(size_of::<WeightUpdate>() == 8, "WeightUpdate must be 8 bytes");
const _: () = assert!(
size_of::<WeightUpdate>() == 8,
"WeightUpdate must be 8 bytes"
);
const _: () = assert!(size_of::<Observation>() == 8, "Observation must be 8 bytes");
const _: () = assert!(size_of::<Delta>() == 16, "Delta must be 16 bytes");

View file

@ -621,7 +621,11 @@ impl EvidenceAccumulator {
fn compute_likelihood_ratio(&self, obs: &Observation) -> f32 {
match obs.obs_type {
Observation::TYPE_CONNECTIVITY => {
if obs.flags != 0 { 1.5 } else { 0.5 }
if obs.flags != 0 {
1.5
} else {
0.5
}
}
Observation::TYPE_CUT_MEMBERSHIP => {
let confidence = (obs.value as f32) / 65535.0;
@ -629,10 +633,18 @@ impl EvidenceAccumulator {
}
Observation::TYPE_FLOW => {
let flow = (obs.value as f32) / 1000.0;
if flow > 0.5 { 1.0 + flow } else { 1.0 / (1.0 + flow) }
if flow > 0.5 {
1.0 + flow
} else {
1.0 / (1.0 + flow)
}
}
Observation::TYPE_WITNESS => {
if obs.flags != 0 { 2.0 } else { 0.5 }
if obs.flags != 0 {
2.0
} else {
0.5
}
}
_ => 1.0,
}

View file

@ -300,7 +300,8 @@ impl TileState {
}
DeltaTag::WeightUpdate => {
let wu = unsafe { delta.get_weight_update() };
self.graph.update_weight(wu.source, wu.target, wu.new_weight);
self.graph
.update_weight(wu.source, wu.target, wu.new_weight);
}
DeltaTag::Observation => {
let obs = unsafe { *delta.get_observation() };
@ -356,12 +357,8 @@ impl TileState {
min_degree as u16 * 100 // weight scale factor
};
let mut fragment = WitnessFragment::new(
seed,
boundary,
self.graph.num_vertices,
local_min_cut,
);
let mut fragment =
WitnessFragment::new(seed, boundary, self.graph.num_vertices, local_min_cut);
fragment.component = self.graph.num_components;
fragment.compute_hash();

View file

@ -268,7 +268,10 @@ impl CompactGraph {
weight: 0,
flags: 0,
}; MAX_SHARD_EDGES],
adjacency: [[AdjEntry { neighbor: 0, edge_id: 0 }; MAX_DEGREE]; MAX_SHARD_VERTICES],
adjacency: [[AdjEntry {
neighbor: 0,
edge_id: 0,
}; MAX_DEGREE]; MAX_SHARD_VERTICES],
}
}
@ -470,7 +473,11 @@ impl CompactGraph {
///
/// SAFETY: Caller must ensure source < MAX_SHARD_VERTICES and vertex is active
#[inline(always)]
pub unsafe fn find_edge_unchecked(&self, source: TileVertexId, target: TileVertexId) -> Option<TileEdgeId> {
pub unsafe fn find_edge_unchecked(
&self,
source: TileVertexId,
target: TileVertexId,
) -> Option<TileEdgeId> {
unsafe {
let entry = self.vertices.get_unchecked(source as usize);
let degree = entry.degree as usize;
@ -682,7 +689,12 @@ impl CompactGraph {
}
/// Remove from adjacency list using swap-remove
fn remove_from_adjacency(&mut self, v: TileVertexId, neighbor: TileVertexId, edge_id: TileEdgeId) {
fn remove_from_adjacency(
&mut self,
v: TileVertexId,
neighbor: TileVertexId,
edge_id: TileEdgeId,
) {
if v as usize >= MAX_SHARD_VERTICES {
return;
}
@ -808,7 +820,10 @@ impl CompactGraph {
/// Iterator of weights from active edges
#[inline]
pub fn active_edge_weights(&self) -> impl Iterator<Item = FixedWeight> + '_ {
self.edges.iter().filter(|e| e.is_active()).map(|e| e.weight)
self.edges
.iter()
.filter(|e| e.is_active())
.map(|e| e.weight)
}
/// Compute total edge weight using SIMD-friendly accumulation

View file

@ -13,12 +13,10 @@ use rand::Rng;
use std::collections::HashMap;
use cognitum_gate_tilezero::{
ActionContext, ActionMetadata, ActionTarget,
GateDecision, GateThresholds, ReducedGraph, ThreeFilterDecision,
TileZero, TileId,
merge::{EdgeSummary, MergeStrategy, NodeSummary, ReportMerger, WorkerReport},
PermitState, PermitToken, ReceiptLog, TimestampProof, WitnessReceipt, WitnessSummary,
EvidenceFilter,
ActionContext, ActionMetadata, ActionTarget, EvidenceFilter, GateDecision, GateThresholds,
PermitState, PermitToken, ReceiptLog, ReducedGraph, ThreeFilterDecision, TileId, TileZero,
TimestampProof, WitnessReceipt, WitnessSummary,
};
// ============================================================================
@ -96,7 +94,11 @@ fn create_worker_report(
for i in 0..boundary_edge_count {
report.add_boundary_edge(EdgeSummary {
source: format!("node-{}-{}", tile_id, i % node_count.max(1)),
target: format!("node-{}-{}", (tile_id as usize + 1) % 256, i % node_count.max(1)),
target: format!(
"node-{}-{}",
(tile_id as usize + 1) % 256,
i % node_count.max(1)
),
capacity: rng.gen_range(1.0..100.0),
is_boundary: true,
});
@ -110,7 +112,11 @@ fn create_worker_report(
}
/// Create all 255 tile reports
fn create_all_tile_reports(epoch: u64, nodes_per_tile: usize, edges_per_tile: usize) -> Vec<WorkerReport> {
fn create_all_tile_reports(
epoch: u64,
nodes_per_tile: usize,
edges_per_tile: usize,
) -> Vec<WorkerReport> {
(1..=255u8)
.map(|tile_id| create_worker_report(tile_id, epoch, nodes_per_tile, edges_per_tile))
.collect()
@ -182,9 +188,7 @@ fn bench_merge_reports(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("255_tiles_minimal", name),
&minimal_reports,
|b, reports| {
b.iter(|| black_box(merger.merge(black_box(reports))))
},
|b, reports| b.iter(|| black_box(merger.merge(black_box(reports)))),
);
}
@ -222,9 +226,8 @@ fn bench_decision(c: &mut Criterion) {
let ctx = create_action_context(0);
group.bench_function("tilezero_full_decision", |b| {
b.to_async(&rt).iter(|| async {
black_box(tilezero.decide(black_box(&ctx)).await)
});
b.to_async(&rt)
.iter(|| async { black_box(tilezero.decide(black_box(&ctx)).await) });
});
// Three-filter decision only (no crypto)
@ -237,13 +240,9 @@ fn bench_decision(c: &mut Criterion) {
];
for (name, graph) in &graph_states {
group.bench_with_input(
BenchmarkId::new("three_filter", name),
graph,
|b, graph| {
b.iter(|| black_box(decision.evaluate(black_box(graph))))
},
);
group.bench_with_input(BenchmarkId::new("three_filter", name), graph, |b, graph| {
b.iter(|| black_box(decision.evaluate(black_box(graph))))
});
}
// Batch decisions
@ -278,9 +277,7 @@ fn bench_receipt_hash(c: &mut Criterion) {
let receipt = create_test_receipt(0, [0u8; 32]);
// Single hash
group.bench_function("hash_single", |b| {
b.iter(|| black_box(receipt.hash()))
});
group.bench_function("hash_single", |b| b.iter(|| black_box(receipt.hash())));
// Hash with varying boundary sizes
for boundary_size in [0, 10, 50, 100] {
@ -292,9 +289,7 @@ fn bench_receipt_hash(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("boundary_size", boundary_size),
&receipt,
|b, receipt| {
b.iter(|| black_box(receipt.hash()))
},
|b, receipt| b.iter(|| black_box(receipt.hash())),
);
}
@ -328,9 +323,7 @@ fn bench_receipt_chain_verify(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("verify_chain", chain_length),
&log,
|b, log| {
b.iter(|| black_box(log.verify_chain_to((chain_length - 1) as u64)))
},
|b, log| b.iter(|| black_box(log.verify_chain_to((chain_length - 1) as u64))),
);
}
@ -376,22 +369,23 @@ fn bench_permit_sign(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("action_len", action_len),
&token,
|b, token| {
b.iter(|| black_box(state.sign_token(token.clone())))
},
|b, token| b.iter(|| black_box(state.sign_token(token.clone()))),
);
}
// Batch signing
for batch_size in [10, 50, 100] {
let tokens: Vec<_> = (0..batch_size).map(|i| create_test_token(i as u64)).collect();
let tokens: Vec<_> = (0..batch_size)
.map(|i| create_test_token(i as u64))
.collect();
group.bench_with_input(
BenchmarkId::new("batch_sign", batch_size),
&tokens,
|b, tokens| {
b.iter(|| {
let signed: Vec<_> = tokens.iter()
let signed: Vec<_> = tokens
.iter()
.cloned()
.map(|t| state.sign_token(t))
.collect();
@ -492,9 +486,7 @@ fn bench_evalue_computation(c: &mut Criterion) {
// SIMD-friendly aggregation patterns
let tile_count = 255;
let e_values: Vec<f64> = (0..tile_count)
.map(|i| 1.0 + (i as f64 * 0.01))
.collect();
let e_values: Vec<f64> = (0..tile_count).map(|i| 1.0 + (i as f64 * 0.01)).collect();
group.bench_function("aggregate_255_scalar", |b| {
b.iter(|| {
@ -619,15 +611,9 @@ fn bench_receipt_log_operations(c: &mut Criterion) {
// Criterion Groups
// ============================================================================
criterion_group!(
merge_benches,
bench_merge_reports,
);
criterion_group!(merge_benches, bench_merge_reports,);
criterion_group!(
decision_benches,
bench_decision,
);
criterion_group!(decision_benches, bench_decision,);
criterion_group!(
crypto_benches,
@ -644,4 +630,9 @@ criterion_group!(
bench_receipt_log_operations,
);
criterion_main!(merge_benches, decision_benches, crypto_benches, additional_benches);
criterion_main!(
merge_benches,
decision_benches,
crypto_benches,
additional_benches
);

View file

@ -8,8 +8,8 @@
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use cognitum_gate_tilezero::{
GateDecision, PermitState, PermitToken, ReceiptLog, TimestampProof,
WitnessReceipt, WitnessSummary,
GateDecision, PermitState, PermitToken, ReceiptLog, TimestampProof, WitnessReceipt,
WitnessSummary,
};
/// Create a test permit token
@ -120,9 +120,7 @@ fn bench_receipt_hashing(c: &mut Criterion) {
let receipt = create_test_receipt(0, [0u8; 32]);
group.bench_function("hash_receipt", |b| {
b.iter(|| black_box(receipt.hash()))
});
group.bench_function("hash_receipt", |b| b.iter(|| black_box(receipt.hash())));
// Benchmark with different summary sizes
for boundary_size in [0, 10, 50, 100] {
@ -134,9 +132,7 @@ fn bench_receipt_hashing(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("hash_boundary_size", boundary_size),
&receipt,
|b, receipt| {
b.iter(|| black_box(receipt.hash()))
},
|b, receipt| b.iter(|| black_box(receipt.hash())),
);
}
@ -160,9 +156,7 @@ fn bench_chain_verification(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("verify_chain", chain_length),
&log,
|b, log| {
b.iter(|| black_box(log.verify_chain_to((chain_length - 1) as u64)))
},
|b, log| b.iter(|| black_box(log.verify_chain_to((chain_length - 1) as u64))),
);
}
@ -257,9 +251,7 @@ fn bench_token_encoding(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("encode_action_len", action_len),
&signed,
|b, token| {
b.iter(|| black_box(token.encode_base64()))
},
|b, token| b.iter(|| black_box(token.encode_base64())),
);
}
@ -285,9 +277,7 @@ fn bench_signable_content(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("action_len", action_len),
&token,
|b, token| {
b.iter(|| black_box(token.signable_content()))
},
|b, token| b.iter(|| black_box(token.signable_content())),
);
}
@ -301,14 +291,10 @@ fn bench_witness_summary_hash(c: &mut Criterion) {
let summary = create_test_summary();
group.bench_function("hash", |b| {
b.iter(|| black_box(summary.hash()))
});
group.bench_function("hash", |b| b.iter(|| black_box(summary.hash())));
// JSON serialization (used in hash)
group.bench_function("to_json", |b| {
b.iter(|| black_box(summary.to_json()))
});
group.bench_function("to_json", |b| b.iter(|| black_box(summary.to_json())));
group.finish();
}
@ -321,7 +307,9 @@ fn bench_batch_signing(c: &mut Criterion) {
group.throughput(Throughput::Elements(batch_size as u64));
let state = PermitState::new();
let tokens: Vec<_> = (0..batch_size).map(|i| create_test_token(i as u64)).collect();
let tokens: Vec<_> = (0..batch_size)
.map(|i| create_test_token(i as u64))
.collect();
group.bench_with_input(
BenchmarkId::new("sequential", batch_size),
@ -342,7 +330,6 @@ fn bench_batch_signing(c: &mut Criterion) {
group.finish();
}
criterion_group!(
benches,
bench_token_signing,

View file

@ -8,8 +8,8 @@ use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criteri
use std::collections::HashMap;
use cognitum_gate_tilezero::{
ActionContext, ActionMetadata, ActionTarget, DecisionOutcome, EvidenceFilter,
GateThresholds, ReducedGraph, ThreeFilterDecision, TileZero,
ActionContext, ActionMetadata, ActionTarget, DecisionOutcome, EvidenceFilter, GateThresholds,
ReducedGraph, ThreeFilterDecision, TileZero,
};
/// Create a realistic action context for benchmarking
@ -30,10 +30,7 @@ fn create_action_context(id: usize) -> ActionContext {
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(),
],
prior_actions: vec!["action-prev-1".to_string(), "action-prev-2".to_string()],
urgency: "normal".to_string(),
},
}
@ -98,15 +95,10 @@ fn bench_full_decision_pipeline(c: &mut Criterion) {
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.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();
@ -174,9 +166,7 @@ fn bench_e_value_simd(c: &mut Criterion) {
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();
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| {
@ -272,13 +262,9 @@ fn bench_witness_summary(c: &mut Criterion) {
});
let summary = graph.witness_summary();
group.bench_function("hash", |b| {
b.iter(|| black_box(summary.hash()))
});
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.bench_function("to_json", |b| b.iter(|| black_box(summary.to_json())));
group.finish();
}

View file

@ -35,7 +35,11 @@ fn create_worker_report(
for i in 0..boundary_edge_count {
report.add_boundary_edge(EdgeSummary {
source: format!("node-{}-{}", tile_id, i % node_count.max(1)),
target: format!("node-{}-{}", (tile_id as usize + 1) % 256, i % node_count.max(1)),
target: format!(
"node-{}-{}",
(tile_id as usize + 1) % 256,
i % node_count.max(1)
),
capacity: rng.gen_range(1.0..100.0),
is_boundary: true,
});
@ -84,9 +88,7 @@ fn bench_merge_255_tiles(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("minimal", name),
&minimal_reports,
|b, reports| {
b.iter(|| black_box(merger.merge(black_box(reports))))
},
|b, reports| b.iter(|| black_box(merger.merge(black_box(reports)))),
);
}
@ -99,9 +101,7 @@ fn bench_merge_255_tiles(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("realistic", name),
&realistic_reports,
|b, reports| {
b.iter(|| black_box(merger.merge(black_box(reports))))
},
|b, reports| b.iter(|| black_box(merger.merge(black_box(reports)))),
);
}
@ -114,9 +114,7 @@ fn bench_merge_255_tiles(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("heavy", name),
&heavy_reports,
|b, reports| {
b.iter(|| black_box(merger.merge(black_box(reports))))
},
|b, reports| b.iter(|| black_box(merger.merge(black_box(reports)))),
);
}
@ -139,9 +137,7 @@ fn bench_merge_scaling(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("tiles", tile_count),
&reports,
|b, reports| {
b.iter(|| black_box(merger.merge(black_box(reports))))
},
|b, reports| b.iter(|| black_box(merger.merge(black_box(reports)))),
);
}
@ -190,9 +186,7 @@ fn bench_node_merging(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("overlap_nodes", overlap),
&reports,
|b, reports| {
b.iter(|| black_box(merger.merge(black_box(reports))))
},
|b, reports| b.iter(|| black_box(merger.merge(black_box(reports)))),
);
}
@ -220,9 +214,7 @@ fn bench_edge_merging(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("edges_per_tile", edge_count),
&reports,
|b, reports| {
b.iter(|| black_box(merger.merge(black_box(reports))))
},
|b, reports| b.iter(|| black_box(merger.merge(black_box(reports)))),
);
}
@ -298,12 +290,16 @@ fn bench_confidence_aggregation(c: &mut Criterion) {
for (name, strategy) in strategies {
let merger = ReportMerger::new(strategy);
group.bench_with_input(BenchmarkId::new("strategy", name), &reports, |b, reports| {
b.iter(|| {
let merged = merger.merge(reports).unwrap();
black_box(merged.confidence)
})
});
group.bench_with_input(
BenchmarkId::new("strategy", name),
&reports,
|b, reports| {
b.iter(|| {
let merged = merger.merge(reports).unwrap();
black_box(merged.confidence)
})
},
);
}
group.finish();

View file

@ -23,8 +23,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("TileZero initialized with thresholds:");
println!(" Min cut: {}", tilezero.thresholds().min_cut);
println!(" Max shift: {}", tilezero.thresholds().max_shift);
println!(" Deny threshold (tau_deny): {}", tilezero.thresholds().tau_deny);
println!(" Permit threshold (tau_permit): {}", tilezero.thresholds().tau_permit);
println!(
" Deny threshold (tau_deny): {}",
tilezero.thresholds().tau_deny
);
println!(
" Permit threshold (tau_permit): {}",
tilezero.thresholds().tau_permit
);
println!();
// Create an action context

View file

@ -18,8 +18,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create TileZero with conservative thresholds to trigger DEFER
let thresholds = GateThresholds {
min_cut: 15.0, // Higher threshold
max_shift: 0.3, // Lower tolerance for shift
min_cut: 15.0, // Higher threshold
max_shift: 0.3, // Lower tolerance for shift
tau_deny: 0.01,
tau_permit: 100.0,
permit_ttl_ns: 300_000_000_000, // 5 minutes
@ -104,7 +104,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!(" - Provide additional context");
}
}
} else {
println!("Decision: {:?}", token.decision);
println!("(Automatic - no human review needed)");

View file

@ -61,7 +61,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Display receipt summary
println!("\nReceipts:");
println!("{:-<60}", "");
println!("{:<10} {:<15} {:<12} {:<20}", "Seq", "Action", "Decision", "Hash (first 8)");
println!(
"{:<10} {:<15} {:<12} {:<20}",
"Seq", "Action", "Decision", "Hash (first 8)"
);
println!("{:-<60}", "");
for seq in 0..actions.len() as u64 {
@ -84,7 +87,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("\nExporting audit log...");
let audit_json = tilezero.export_receipts_json().await?;
let filename = format!("audit_log_{}.json",
let filename = format!(
"audit_log_{}.json",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()

View file

@ -96,7 +96,13 @@ pub struct DecisionOutcome {
impl DecisionOutcome {
/// Create a permit outcome
#[inline]
pub fn permit(confidence: f64, structural: f64, shift: f64, evidence: f64, mincut: f64) -> Self {
pub fn permit(
confidence: f64,
structural: f64,
shift: f64,
evidence: f64,
mincut: f64,
) -> Self {
Self {
decision: GateDecision::Permit,
confidence,

View file

@ -193,10 +193,7 @@ pub fn aggregate_tiles_simd(tile_e_values: &[f64]) -> f64 {
///
/// # Returns
/// Weighted geometric mean of e-values
pub fn mixture_evalue_adaptive(
log_e_values: &[f64],
weights: Option<&[f64]>,
) -> f64 {
pub fn mixture_evalue_adaptive(log_e_values: &[f64], weights: Option<&[f64]>) -> f64 {
if log_e_values.is_empty() {
return 1.0;
}

View file

@ -13,7 +13,10 @@ pub mod permit;
pub mod receipt;
pub mod supergraph;
pub use decision::{DecisionFilter, DecisionOutcome, EvidenceDecision, GateDecision, GateThresholds, ThreeFilterDecision};
pub use decision::{
DecisionFilter, DecisionOutcome, EvidenceDecision, GateDecision, GateThresholds,
ThreeFilterDecision,
};
pub use evidence::{AggregatedEvidence, EvidenceFilter};
pub use merge::{MergeStrategy, MergedReport, ReportMerger, WorkerReport};
pub use permit::{PermitState, PermitToken, TokenDecodeError, Verifier, VerifyError};

View file

@ -350,10 +350,10 @@ impl ReportMerger {
}
MergeStrategy::WeightedAverage => {
// OPTIMIZATION: Single pass for both sums
let (weighted_sum, coherence_sum) = data.iter().fold(
(0.0, 0.0),
|(ws, cs), (_, n)| (ws + n.weight * n.coherence, cs + n.coherence),
);
let (weighted_sum, coherence_sum) =
data.iter().fold((0.0, 0.0), |(ws, cs), (_, n)| {
(ws + n.weight * n.coherence, cs + n.coherence)
});
if coherence_sum > 0.0 {
weighted_sum / coherence_sum
} else {

View file

@ -282,8 +282,8 @@ mod tests {
let token = PermitToken {
decision: GateDecision::Permit,
action_id: "test-action".to_string(),
timestamp: 1000000000, // Long ago
ttl_ns: 1, // 1 nanosecond TTL
timestamp: 1000000000, // Long ago
ttl_ns: 1, // 1 nanosecond TTL
witness_hash: [0u8; 32],
sequence: 0,
signature: [0u8; 64],
@ -295,6 +295,9 @@ mod tests {
assert!(verifier.verify(&signed).is_ok());
// But full verification (including TTL) should fail
assert!(matches!(verifier.verify_full(&signed), Err(VerifyError::Expired)));
assert!(matches!(
verifier.verify_full(&signed),
Err(VerifyError::Expired)
));
}
}

View file

@ -1,7 +1,7 @@
//! Reduced supergraph from worker tile summaries
use crate::{TileId, WitnessFragment};
use crate::receipt::WitnessSummary;
use crate::{TileId, WitnessFragment};
use std::collections::HashMap;
/// Reduced graph maintained by TileZero
@ -23,7 +23,7 @@ impl ReducedGraph {
pub fn new() -> Self {
Self {
tile_coherence: HashMap::new(),
global_cut_value: 100.0, // Start with high coherence
global_cut_value: 100.0, // Start with high coherence
aggregated_e_value: 100.0, // Start with high evidence
shift_pressure: 0.0,
boundary_edges: 0,

View file

@ -399,7 +399,11 @@ mod serialization {
#[test]
fn test_decision_serialization() {
let decisions = [GateDecision::Permit, GateDecision::Defer, GateDecision::Deny];
let decisions = [
GateDecision::Permit,
GateDecision::Defer,
GateDecision::Deny,
];
for decision in &decisions {
let json = serde_json::to_string(decision).unwrap();

View file

@ -7,8 +7,7 @@
//! - Property-based tests for merge invariants
use cognitum_gate_tilezero::merge::{
EdgeSummary, MergeError, MergeStrategy, MergedReport, NodeSummary, ReportMerger,
WorkerReport,
EdgeSummary, MergeError, MergeStrategy, MergedReport, NodeSummary, ReportMerger, WorkerReport,
};
fn create_test_report(tile_id: u8, epoch: u64) -> WorkerReport {

View file

@ -6,7 +6,9 @@
//! - TTL validation
//! - Security tests (invalid signatures, replay attacks, tamper detection)
use cognitum_gate_tilezero::permit::{PermitState, PermitToken, TokenDecodeError, Verifier, VerifyError};
use cognitum_gate_tilezero::permit::{
PermitState, PermitToken, TokenDecodeError, Verifier, VerifyError,
};
use cognitum_gate_tilezero::GateDecision;
fn create_test_token(action_id: &str, sequence: u64) -> PermitToken {
@ -372,10 +374,8 @@ mod base64_encoding {
#[test]
fn test_decode_invalid_json() {
// Valid base64 but not JSON
let encoded = base64::Engine::encode(
&base64::engine::general_purpose::STANDARD,
b"not json",
);
let encoded =
base64::Engine::encode(&base64::engine::general_purpose::STANDARD, b"not json");
let result = PermitToken::decode_base64(&encoded);
assert!(matches!(result, Err(TokenDecodeError::InvalidJson)));
}

View file

@ -6,11 +6,11 @@
//! - Tamper detection
//! - Security tests (chain manipulation, replay attacks)
use cognitum_gate_tilezero::permit::PermitToken;
use cognitum_gate_tilezero::receipt::{
EvidentialWitness, PredictiveWitness, ReceiptLog, StructuralWitness, TimestampProof,
WitnessReceipt, WitnessSummary,
};
use cognitum_gate_tilezero::permit::PermitToken;
use cognitum_gate_tilezero::GateDecision;
fn create_test_token(sequence: u64, action_id: &str) -> PermitToken {

View file

@ -8,8 +8,7 @@ use tracing_subscriber::{fmt, prelude::*, EnvFilter};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize logging
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("info"));
let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info"));
tracing_subscriber::registry()
.with(fmt::layer().with_writer(std::io::stderr))
@ -22,10 +21,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create and run server
let server = McpGateServer::with_thresholds(config.thresholds);
tracing::info!(
"MCP Gate server v{} starting",
env!("CARGO_PKG_VERSION")
);
tracing::info!("MCP Gate server v{} starting", env!("CARGO_PKG_VERSION"));
server.run_stdio().await?;

View file

@ -380,10 +380,8 @@ mod tests {
#[test]
fn test_jsonrpc_response() {
let resp = JsonRpcResponse::success(
serde_json::json!(1),
serde_json::json!({"status": "ok"}),
);
let resp =
JsonRpcResponse::success(serde_json::json!(1), serde_json::json!({"status": "ok"}));
assert_eq!(resp.jsonrpc, "2.0");
assert!(resp.result.is_some());
assert!(resp.error.is_none());

View file

@ -6,9 +6,7 @@ fn attention_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("attention");
// Placeholder benchmark - requires attention feature
group.bench_function("placeholder", |b| {
b.iter(|| black_box(42))
});
group.bench_function("placeholder", |b| b.iter(|| black_box(42)));
group.finish();
}

View file

@ -6,9 +6,7 @@ fn coherence_benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("coherence");
// Placeholder benchmark - will be implemented when coherence module is complete
group.bench_function("placeholder", |b| {
b.iter(|| black_box(42))
});
group.bench_function("placeholder", |b| b.iter(|| black_box(42)));
group.finish();
}

View file

@ -13,9 +13,7 @@
//! 2. Restriction Maps - identity, diagonal, dense, sparse
//! 3. Scaling Tests - nodes, edges, dimensions
use criterion::{
black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput,
};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use std::collections::HashMap;
// ============================================================================
@ -532,11 +530,9 @@ fn bench_energy_computation(c: &mut Criterion) {
group.sample_size(sample_size);
group.throughput(Throughput::Elements(graph.edges.len() as u64));
group.bench_with_input(
BenchmarkId::new("nodes", num_nodes),
&num_nodes,
|b, _| b.iter(|| black_box(graph.compute_total_energy())),
);
group.bench_with_input(BenchmarkId::new("nodes", num_nodes), &num_nodes, |b, _| {
b.iter(|| black_box(graph.compute_total_energy()))
});
}
group.finish();
@ -577,7 +573,11 @@ fn bench_incremental_update(c: &mut Criterion) {
node.state = new_state;
}
let affected = self.node_to_edges.get(&node_id).cloned().unwrap_or_default();
let affected = self
.node_to_edges
.get(&node_id)
.cloned()
.unwrap_or_default();
let mut source_buf = vec![0.0f32; self.graph.edge_dim];
let mut target_buf = vec![0.0f32; self.graph.edge_dim];
@ -793,8 +793,14 @@ fn bench_restriction_map_types(c: &mut Criterion) {
// Identity maps
{
let graph =
SheafGraph::with_restriction_type(num_nodes, 4, state_dim, state_dim, MapType::Identity, 42);
let graph = SheafGraph::with_restriction_type(
num_nodes,
4,
state_dim,
state_dim,
MapType::Identity,
42,
);
group.throughput(Throughput::Elements(graph.edges.len() as u64));
group.bench_function("identity", |b| {
b.iter(|| black_box(graph.compute_total_energy()))
@ -803,8 +809,14 @@ fn bench_restriction_map_types(c: &mut Criterion) {
// Diagonal maps
{
let graph =
SheafGraph::with_restriction_type(num_nodes, 4, state_dim, state_dim, MapType::Diagonal, 42);
let graph = SheafGraph::with_restriction_type(
num_nodes,
4,
state_dim,
state_dim,
MapType::Diagonal,
42,
);
group.bench_function("diagonal", |b| {
b.iter(|| black_box(graph.compute_total_energy()))
});
@ -812,8 +824,14 @@ fn bench_restriction_map_types(c: &mut Criterion) {
// Dense maps
{
let graph =
SheafGraph::with_restriction_type(num_nodes, 4, state_dim, state_dim, MapType::Dense, 42);
let graph = SheafGraph::with_restriction_type(
num_nodes,
4,
state_dim,
state_dim,
MapType::Dense,
42,
);
group.bench_function("dense", |b| {
b.iter(|| black_box(graph.compute_total_energy()))
});
@ -901,7 +919,9 @@ fn bench_batch_residual(c: &mut Criterion) {
})
.collect();
let states: Vec<Vec<f32>> = (0..batch_size + 1).map(|i| generate_state(dim, i as u64)).collect();
let states: Vec<Vec<f32>> = (0..batch_size + 1)
.map(|i| generate_state(dim, i as u64))
.collect();
group.throughput(Throughput::Elements(batch_size as u64));
@ -967,7 +987,15 @@ fn bench_memory_patterns(c: &mut Criterion) {
// Chain graph (sequential access)
{
let nodes: HashMap<u64, SheafNode> = (0..num_nodes as u64)
.map(|id| (id, SheafNode { id, state: generate_state(dim, id) }))
.map(|id| {
(
id,
SheafNode {
id,
state: generate_state(dim, id),
},
)
})
.collect();
let edges: Vec<SheafEdge> = (0..num_nodes - 1)

View file

@ -409,11 +409,9 @@ fn bench_state_dimension(c: &mut Criterion) {
let graph = SheafGraph::random(num_nodes, avg_degree, state_dim, 42);
group.throughput(Throughput::Elements(graph.edges.len() as u64));
group.bench_with_input(
BenchmarkId::new("dim", state_dim),
&state_dim,
|b, _| b.iter(|| black_box(graph.compute_total_energy())),
);
group.bench_with_input(BenchmarkId::new("dim", state_dim), &state_dim, |b, _| {
b.iter(|| black_box(graph.compute_total_energy()))
});
}
group.finish();

View file

@ -109,7 +109,9 @@ pub struct EnergyHistory {
impl EnergyHistory {
pub fn new(max_scopes: usize, window_size: usize) -> Self {
Self {
history: (0..max_scopes).map(|_| VecDeque::with_capacity(window_size)).collect(),
history: (0..max_scopes)
.map(|_| VecDeque::with_capacity(window_size))
.collect(),
max_scopes,
window_size,
}
@ -140,10 +142,7 @@ impl EnergyHistory {
let cutoff = current_time_ms.saturating_sub(window_ms);
// Check if all samples in window are above threshold
let samples_in_window: Vec<_> = queue
.iter()
.filter(|(ts, _)| *ts >= cutoff)
.collect();
let samples_in_window: Vec<_> = queue.iter().filter(|(ts, _)| *ts >= cutoff).collect();
if samples_in_window.is_empty() {
return false;
@ -160,10 +159,7 @@ impl EnergyHistory {
let queue = &self.history[scope_id as usize];
let cutoff = current_time_ms.saturating_sub(window_ms);
let samples: Vec<_> = queue
.iter()
.filter(|(ts, _)| *ts >= cutoff)
.collect();
let samples: Vec<_> = queue.iter().filter(|(ts, _)| *ts >= cutoff).collect();
if samples.len() < 2 {
return None;
@ -257,7 +253,8 @@ impl CoherenceGate {
let current_energy = energy.scope_energy(action.scope_id);
// Record in history
self.history.record(action.scope_id, self.current_time_ms, current_energy);
self.history
.record(action.scope_id, self.current_time_ms, current_energy);
// Determine lane based on energy
let lane = if current_energy < self.config.reflex {
@ -279,8 +276,13 @@ impl CoherenceGate {
);
// Check for growing incoherence (trend)
let growing = self.history
.trend(action.scope_id, self.config.persistence_window_ms, self.current_time_ms)
let growing = self
.history
.trend(
action.scope_id,
self.config.persistence_window_ms,
self.current_time_ms,
)
.map(|t| t > 0.01)
.unwrap_or(false);
@ -404,9 +406,7 @@ fn bench_gate_fast_path(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("evaluate_fast", format!("{:.2}", energy)),
&energy,
|b, &e| {
b.iter(|| black_box(gate.evaluate_fast(black_box(e))))
},
|b, &e| b.iter(|| black_box(gate.evaluate_fast(black_box(e)))),
);
}
@ -466,20 +466,13 @@ fn bench_history_operations(c: &mut Criterion) {
// Check threshold
group.bench_function("check_threshold", |b| {
b.iter(|| {
history.is_above_threshold(
black_box(5),
black_box(0.3),
black_box(100),
black_box(500),
)
history.is_above_threshold(black_box(5), black_box(0.3), black_box(100), black_box(500))
})
});
// Compute trend
group.bench_function("compute_trend", |b| {
b.iter(|| {
history.trend(black_box(5), black_box(100), black_box(500))
})
b.iter(|| history.trend(black_box(5), black_box(100), black_box(500)))
});
group.finish();

View file

@ -18,9 +18,7 @@
//! cargo bench --features gpu --bench gpu_benchmarks
//! ```
use criterion::{
black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput,
};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
@ -222,7 +220,11 @@ fn batch_routing_cpu(
// Sort by score (descending) and take top-k
expert_scores.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
let top_experts: Vec<usize> = expert_scores.iter().take(top_k).map(|(idx, _)| *idx).collect();
let top_experts: Vec<usize> = expert_scores
.iter()
.take(top_k)
.map(|(idx, _)| *idx)
.collect();
results.push((t, top_experts));
}
@ -254,7 +256,7 @@ mod gpu_impl {
// Simulate GPU overhead
let _upload_time = simulate_memory_transfer(
graph.nodes.len() * graph.state_dim * 4, // bytes
true, // host to device
true, // host to device
);
// Actual computation would happen on GPU
@ -427,9 +429,9 @@ fn bench_attention_cpu_vs_gpu(c: &mut Criterion) {
// Typical attention configurations
let configs = [
(128, 64, "small"), // seq_len=128, head_dim=64
(512, 64, "medium"), // seq_len=512, head_dim=64
(2048, 64, "large"), // seq_len=2048, head_dim=64
(128, 64, "small"), // seq_len=128, head_dim=64
(512, 64, "medium"), // seq_len=512, head_dim=64
(2048, 64, "large"), // seq_len=2048, head_dim=64
];
for (seq_len, head_dim, label) in configs {
@ -759,10 +761,7 @@ criterion_group!(
bench_multihead_attention,
);
criterion_group!(
routing_benches,
bench_batch_routing_cpu_vs_gpu,
);
criterion_group!(routing_benches, bench_batch_routing_cpu_vs_gpu,);
criterion_group!(
transfer_benches,

View file

@ -374,7 +374,9 @@ fn bench_knn_hyperbolic(c: &mut Criterion) {
let dim = 64;
let curvature = -1.0;
let points: Vec<Vec<f32>> = (0..1000).map(|i| generate_point(dim, i as u64, 0.9)).collect();
let points: Vec<Vec<f32>> = (0..1000)
.map(|i| generate_point(dim, i as u64, 0.9))
.collect();
let query = generate_point(dim, 999, 0.9);
for k in [1, 5, 10, 50] {
@ -389,7 +391,10 @@ fn bench_knn_hyperbolic(c: &mut Criterion) {
// Partial sort for k-nearest
distances.sort_by(|a, b| a.1.partial_cmp(&b.1).unwrap());
let result = distances[..k].iter().map(|(i, d)| (*i, *d)).collect::<Vec<_>>();
let result = distances[..k]
.iter()
.map(|(i, d)| (*i, *d))
.collect::<Vec<_>>();
black_box(result)
})
});
@ -460,9 +465,7 @@ fn bench_curvature_impact(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("curvature", format!("{:.1}", curvature)),
&curvature,
|b, &c| {
b.iter(|| poincare_distance(black_box(&x), black_box(&y), black_box(c)))
},
|b, &c| b.iter(|| poincare_distance(black_box(&x), black_box(&y), black_box(c))),
);
}

View file

@ -266,7 +266,11 @@ fn generate_state(dim: usize, seed: u64) -> Vec<f32> {
.collect()
}
fn create_random_graph(num_nodes: usize, avg_degree: usize, state_dim: usize) -> IncrementalCoherence {
fn create_random_graph(
num_nodes: usize,
avg_degree: usize,
state_dim: usize,
) -> IncrementalCoherence {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
@ -487,14 +491,18 @@ fn bench_state_dim_impact(c: &mut Criterion) {
for state_dim in [8, 32, 64, 128, 256] {
let mut tracker = create_random_graph(num_nodes, avg_degree, state_dim);
group.bench_with_input(BenchmarkId::new("update", state_dim), &state_dim, |b, &dim| {
let node_id = 5000u64;
b.iter(|| {
let new_state = generate_state(dim, rand::random());
tracker.update_node(black_box(node_id), new_state);
black_box(tracker.energy())
})
});
group.bench_with_input(
BenchmarkId::new("update", state_dim),
&state_dim,
|b, &dim| {
let node_id = 5000u64;
b.iter(|| {
let new_state = generate_state(dim, rand::random());
tracker.update_node(black_box(node_id), new_state);
black_box(tracker.energy())
})
},
);
}
group.finish();

View file

@ -193,7 +193,12 @@ impl DynamicGraph {
GraphStats {
vertices: self.vertex_count,
edges: self.edge_count,
max_degree: self.adjacency.values().map(|adj| adj.len()).max().unwrap_or(0),
max_degree: self
.adjacency
.values()
.map(|adj| adj.len())
.max()
.unwrap_or(0),
avg_degree: if self.vertex_count > 0 {
(self.edge_count * 2) as f64 / self.vertex_count as f64
} else {
@ -316,7 +321,11 @@ impl SubpolynomialMinCut {
} else {
// Multiple components - use first vs rest
let left = components[0].clone();
let right: HashSet<_> = components[1..].iter().flat_map(|c| c.iter()).copied().collect();
let right: HashSet<_> = components[1..]
.iter()
.flat_map(|c| c.iter())
.copied()
.collect();
(left, right)
}
}
@ -375,18 +384,14 @@ fn bench_insert_edge(c: &mut Criterion) {
mincut.insert_edge(*u, *v, *w);
}
group.bench_with_input(
BenchmarkId::new("insert_single", size),
&size,
|b, &n| {
let mut i = edges.len() / 2;
b.iter(|| {
let (u, v, w) = edges[i % edges.len()];
black_box(mincut.insert_edge(u + n as u64, v + n as u64, w));
i += 1;
})
},
);
group.bench_with_input(BenchmarkId::new("insert_single", size), &size, |b, &n| {
let mut i = edges.len() / 2;
b.iter(|| {
let (u, v, w) = edges[i % edges.len()];
black_box(mincut.insert_edge(u + n as u64, v + n as u64, w));
i += 1;
})
});
}
group.finish();
@ -520,45 +525,41 @@ fn bench_mixed_workload(c: &mut Criterion) {
for size in [100, 1000, 10000] {
let edges = generate_random_graph(size, size * 2, 42);
group.bench_with_input(
BenchmarkId::new("mixed_ops", size),
&size,
|b, &n| {
b.iter_batched(
|| {
let mut mincut = SubpolynomialMinCut::with_capacity(n, n * 3);
for (u, v, w) in &edges {
mincut.insert_edge(*u, *v, *w);
}
(mincut, 0usize)
},
|(mut mincut, mut op_idx)| {
// 50% insert, 30% delete, 20% query
match op_idx % 10 {
0..=4 => {
let u = (op_idx * 37) as u64 % n as u64;
let v = (op_idx * 73 + 1) as u64 % n as u64;
if u != v {
mincut.insert_edge(u + n as u64, v + n as u64, 1.0);
}
}
5..=7 => {
if !edges.is_empty() {
let (u, v, _) = edges[op_idx % edges.len()];
mincut.delete_edge(u, v);
}
}
_ => {
let _ = mincut.min_cut();
group.bench_with_input(BenchmarkId::new("mixed_ops", size), &size, |b, &n| {
b.iter_batched(
|| {
let mut mincut = SubpolynomialMinCut::with_capacity(n, n * 3);
for (u, v, w) in &edges {
mincut.insert_edge(*u, *v, *w);
}
(mincut, 0usize)
},
|(mut mincut, mut op_idx)| {
// 50% insert, 30% delete, 20% query
match op_idx % 10 {
0..=4 => {
let u = (op_idx * 37) as u64 % n as u64;
let v = (op_idx * 73 + 1) as u64 % n as u64;
if u != v {
mincut.insert_edge(u + n as u64, v + n as u64, 1.0);
}
}
op_idx += 1;
black_box(op_idx)
},
criterion::BatchSize::SmallInput,
)
},
);
5..=7 => {
if !edges.is_empty() {
let (u, v, _) = edges[op_idx % edges.len()];
mincut.delete_edge(u, v);
}
}
_ => {
let _ = mincut.min_cut();
}
}
op_idx += 1;
black_box(op_idx)
},
criterion::BatchSize::SmallInput,
)
});
}
group.finish();

View file

@ -219,15 +219,9 @@ fn bench_single_residual(c: &mut Criterion) {
rho_target,
};
group.bench_with_input(
BenchmarkId::new("identity_map", dim),
&dim,
|b, _| {
b.iter(|| {
edge.residual(black_box(&source_state), black_box(&target_state))
})
},
);
group.bench_with_input(BenchmarkId::new("identity_map", dim), &dim, |b, _| {
b.iter(|| edge.residual(black_box(&source_state), black_box(&target_state)))
});
}
// Test with projection (non-identity maps)
@ -248,11 +242,7 @@ fn bench_single_residual(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("projection_map", format!("{}to{}", input_dim, output_dim)),
&(input_dim, output_dim),
|b, _| {
b.iter(|| {
edge.residual(black_box(&source_state), black_box(&target_state))
})
},
|b, _| b.iter(|| edge.residual(black_box(&source_state), black_box(&target_state))),
);
}
@ -407,9 +397,7 @@ fn bench_restriction_map(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("identity_apply_into", dim),
&dim,
|b, _| {
b.iter(|| rho.apply_into(black_box(&input), black_box(&mut output)))
},
|b, _| b.iter(|| rho.apply_into(black_box(&input), black_box(&mut output))),
);
}
@ -426,11 +414,12 @@ fn bench_restriction_map(c: &mut Criterion) {
);
group.bench_with_input(
BenchmarkId::new("projection_apply_into", format!("{}x{}", input_dim, output_dim)),
BenchmarkId::new(
"projection_apply_into",
format!("{}x{}", input_dim, output_dim),
),
&(input_dim, output_dim),
|b, _| {
b.iter(|| rho.apply_into(black_box(&input), black_box(&mut output)))
},
|b, _| b.iter(|| rho.apply_into(black_box(&input), black_box(&mut output))),
);
}
@ -448,45 +437,57 @@ fn bench_simd_patterns(c: &mut Criterion) {
let b = generate_state(dim, 123);
// Scalar subtraction and norm
group.bench_with_input(BenchmarkId::new("scalar_diff_norm", dim), &dim, |b_iter, _| {
b_iter.iter(|| {
let mut norm_sq = 0.0f32;
for i in 0..dim {
let diff = a[i] - b[i];
norm_sq += diff * diff;
}
black_box(norm_sq)
})
});
group.bench_with_input(
BenchmarkId::new("scalar_diff_norm", dim),
&dim,
|b_iter, _| {
b_iter.iter(|| {
let mut norm_sq = 0.0f32;
for i in 0..dim {
let diff = a[i] - b[i];
norm_sq += diff * diff;
}
black_box(norm_sq)
})
},
);
// Iterator-based (auto-vectorization friendly)
group.bench_with_input(BenchmarkId::new("iter_diff_norm", dim), &dim, |b_iter, _| {
b_iter.iter(|| {
let norm_sq: f32 = a
.iter()
.zip(b.iter())
.map(|(x, y)| {
let d = x - y;
d * d
})
.sum();
black_box(norm_sq)
})
});
group.bench_with_input(
BenchmarkId::new("iter_diff_norm", dim),
&dim,
|b_iter, _| {
b_iter.iter(|| {
let norm_sq: f32 = a
.iter()
.zip(b.iter())
.map(|(x, y)| {
let d = x - y;
d * d
})
.sum();
black_box(norm_sq)
})
},
);
// Chunked for explicit SIMD opportunity
group.bench_with_input(BenchmarkId::new("chunked_diff_norm", dim), &dim, |b_iter, _| {
b_iter.iter(|| {
let mut accum = [0.0f32; 8];
for (chunk_a, chunk_b) in a.chunks(8).zip(b.chunks(8)) {
for i in 0..chunk_a.len() {
let d = chunk_a[i] - chunk_b[i];
accum[i] += d * d;
group.bench_with_input(
BenchmarkId::new("chunked_diff_norm", dim),
&dim,
|b_iter, _| {
b_iter.iter(|| {
let mut accum = [0.0f32; 8];
for (chunk_a, chunk_b) in a.chunks(8).zip(b.chunks(8)) {
for i in 0..chunk_a.len() {
let d = chunk_a[i] - chunk_b[i];
accum[i] += d * d;
}
}
}
black_box(accum.iter().sum::<f32>())
})
});
black_box(accum.iter().sum::<f32>())
})
},
);
}
group.finish();

View file

@ -14,9 +14,7 @@
//! - aarch64: NEON (128-bit, f32x4)
//! - WASM: SIMD128 (128-bit)
use criterion::{
black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput,
};
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, Throughput};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
@ -405,26 +403,14 @@ fn bench_dense_matmul(c: &mut Criterion) {
group.bench_with_input(BenchmarkId::new("naive", size), &size, |b, _| {
b.iter(|| {
matmul_naive(
black_box(&matrix),
black_box(&x),
&mut y,
size,
size,
);
matmul_naive(black_box(&matrix), black_box(&x), &mut y, size, size);
black_box(y[0])
})
});
group.bench_with_input(BenchmarkId::new("unrolled", size), &size, |b, _| {
b.iter(|| {
matmul_unrolled(
black_box(&matrix),
black_box(&x),
&mut y,
size,
size,
);
matmul_unrolled(black_box(&matrix), black_box(&x), &mut y, size, size);
black_box(y[0])
})
});
@ -432,13 +418,7 @@ fn bench_dense_matmul(c: &mut Criterion) {
#[cfg(feature = "simd")]
group.bench_with_input(BenchmarkId::new("simd", size), &size, |b, _| {
b.iter(|| {
simd_impl::matmul_simd(
black_box(&matrix),
black_box(&x),
&mut y,
size,
size,
);
simd_impl::matmul_simd(black_box(&matrix), black_box(&x), &mut y, size, size);
black_box(y[0])
})
});
@ -464,13 +444,7 @@ fn bench_projection_matmul(c: &mut Criterion) {
&(in_dim, out_dim),
|b, _| {
b.iter(|| {
matmul_naive(
black_box(&matrix),
black_box(&x),
&mut y,
out_dim,
in_dim,
);
matmul_naive(black_box(&matrix), black_box(&x), &mut y, out_dim, in_dim);
black_box(y[0])
})
},
@ -481,13 +455,7 @@ fn bench_projection_matmul(c: &mut Criterion) {
&(in_dim, out_dim),
|b, _| {
b.iter(|| {
matmul_unrolled(
black_box(&matrix),
black_box(&x),
&mut y,
out_dim,
in_dim,
);
matmul_unrolled(black_box(&matrix), black_box(&x), &mut y, out_dim, in_dim);
black_box(y[0])
})
},
@ -636,7 +604,12 @@ fn bench_batch_residual(c: &mut Criterion) {
BenchmarkId::new("naive", batch_size),
&batch_size,
|b, _| {
b.iter(|| black_box(batch_residual_naive(black_box(&sources), black_box(&targets))))
b.iter(|| {
black_box(batch_residual_naive(
black_box(&sources),
black_box(&targets),
))
})
},
);
@ -728,9 +701,14 @@ fn bench_throughput_scaling(c: &mut Criterion) {
);
#[cfg(feature = "simd")]
group.bench_with_input(BenchmarkId::new("residual_simd", size), &size, |bench, _| {
bench.iter(|| black_box(simd_impl::residual_norm_simd(black_box(&a), black_box(&b))))
});
group.bench_with_input(
BenchmarkId::new("residual_simd", size),
&size,
|bench, _| {
bench
.iter(|| black_box(simd_impl::residual_norm_simd(black_box(&a), black_box(&b))))
},
);
}
group.finish();
@ -796,11 +774,7 @@ fn bench_fma_pattern(c: &mut Criterion) {
// CRITERION CONFIGURATION
// ============================================================================
criterion_group!(
matmul_benches,
bench_dense_matmul,
bench_projection_matmul,
);
criterion_group!(matmul_benches, bench_dense_matmul, bench_projection_matmul,);
criterion_group!(
vector_ops_benches,
@ -809,10 +783,7 @@ criterion_group!(
bench_residual_norm,
);
criterion_group!(
batch_benches,
bench_batch_residual,
);
criterion_group!(batch_benches, bench_batch_residual,);
criterion_group!(
optimization_benches,

View file

@ -392,9 +392,7 @@ fn bench_ewc_penalty(c: &mut Criterion) {
for param_count in [1000, 10000, 100000] {
let ewc = EwcPlusPlus::new(param_count, 0.4);
let weights: Vec<f32> = (0..param_count)
.map(|i| (i as f32 * 0.001).sin())
.collect();
let weights: Vec<f32> = (0..param_count).map(|i| (i as f32 * 0.001).sin()).collect();
group.bench_with_input(
BenchmarkId::new("params", param_count),
@ -412,9 +410,7 @@ fn bench_ewc_consolidate(c: &mut Criterion) {
for param_count in [1000, 10000, 100000] {
let mut ewc = EwcPlusPlus::new(param_count, 0.4);
let weights: Vec<f32> = (0..param_count)
.map(|i| (i as f32 * 0.001).sin())
.collect();
let weights: Vec<f32> = (0..param_count).map(|i| (i as f32 * 0.001).sin()).collect();
let new_fisher: Vec<f32> = (0..param_count)
.map(|i| (i as f32 * 0.002).cos().abs())
.collect();
@ -422,9 +418,7 @@ fn bench_ewc_consolidate(c: &mut Criterion) {
group.bench_with_input(
BenchmarkId::new("params", param_count),
&param_count,
|b, _| {
b.iter(|| ewc.consolidate(black_box(&weights), black_box(&new_fisher)))
},
|b, _| b.iter(|| ewc.consolidate(black_box(&weights), black_box(&new_fisher))),
);
}

View file

@ -271,7 +271,8 @@ impl TileState {
for delta in self.delta_buffer.drain(..) {
match delta.delta_type {
DeltaType::EdgeAdd => {
self.graph.add_edge(delta.source, delta.target, delta.weight);
self.graph
.add_edge(delta.source, delta.target, delta.weight);
}
DeltaType::Observation => {
// Update evidence accumulator
@ -385,9 +386,7 @@ fn bench_single_tile_tick(c: &mut Criterion) {
// Empty tick
let mut tile = TileState::new(0);
group.bench_function("empty", |b| {
b.iter(|| black_box(tile.tick(black_box(1))))
});
group.bench_function("empty", |b| b.iter(|| black_box(tile.tick(black_box(1)))));
// Tick with small graph
let mut tile = TileState::new(0);

View file

@ -43,7 +43,8 @@ impl AttentionAdapter {
for i in 0..n {
for j in 0..n {
if i != j {
similarity_matrix[i][j] = self.cosine_similarity(node_states[i], node_states[j]);
similarity_matrix[i][j] =
self.cosine_similarity(node_states[i], node_states[j]);
}
}
}
@ -238,7 +239,9 @@ mod tests {
let key_refs: Vec<&[f32]> = keys.iter().map(|k| k.as_slice()).collect();
let value_refs: Vec<&[f32]> = values.iter().map(|v| v.as_slice()).collect();
let output = adapter.compute_attention(&query, &key_refs, &value_refs).unwrap();
let output = adapter
.compute_attention(&query, &key_refs, &value_refs)
.unwrap();
assert_eq!(output.len(), 16);
}

View file

@ -241,8 +241,8 @@ impl AttentionCoherence {
// Aggregate
let total_energy: f32 = weighted.iter().map(|w| w.weighted_energy).sum();
let avg_attention: f32 = weighted.iter().map(|w| w.attention_weight).sum::<f32>()
/ weighted.len().max(1) as f32;
let avg_attention: f32 =
weighted.iter().map(|w| w.attention_weight).sum::<f32>() / weighted.len().max(1) as f32;
Ok(AttentionEnergyAnalysis {
weighted_residuals: weighted,
@ -331,9 +331,7 @@ mod tests {
use super::*;
fn make_states(n: usize, dim: usize) -> Vec<Vec<f32>> {
(0..n)
.map(|i| vec![0.1 * (i + 1) as f32; dim])
.collect()
(0..n).map(|i| vec![0.1 * (i + 1) as f32; dim]).collect()
}
#[test]
@ -372,7 +370,9 @@ mod tests {
(2, 3, vec![0.3f32; 8]),
];
let weighted = coherence.weighted_residuals(&state_refs, &residuals).unwrap();
let weighted = coherence
.weighted_residuals(&state_refs, &residuals)
.unwrap();
assert_eq!(weighted.len(), 3);
for w in &weighted {

View file

@ -347,7 +347,8 @@ mod tests {
let inputs: Vec<Vec<f32>> = (0..10).map(|i| vec![0.1 * (i + 1) as f32; 8]).collect();
let context = vec![0.1f32; 8];
let routings: Vec<ExpertRouting> = inputs.iter().map(|inp| moe.route(inp, &context)).collect();
let routings: Vec<ExpertRouting> =
inputs.iter().map(|inp| moe.route(inp, &context)).collect();
let usage = moe.expert_usage(&routings);

View file

@ -2,8 +2,8 @@
//!
//! Uses topological coherence as a permission signal for attention behavior.
use super::{AttentionCoherenceConfig, AttentionError, Result};
use super::config::AttentionMode;
use super::{AttentionCoherenceConfig, AttentionError, Result};
/// Score from attention computation
#[derive(Debug, Clone)]
@ -171,7 +171,8 @@ impl TopologyGate {
.map(|(j, &s)| (j, s))
.collect();
neighbor_sims.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
neighbor_sims
.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
let neighbors: Vec<usize> = neighbor_sims.iter().take(k).map(|(j, _)| *j).collect();
// Boundary mass: edges to non-neighbors
@ -187,7 +188,12 @@ impl TopologyGate {
let all_sims: Vec<f32> = similarities
.iter()
.enumerate()
.flat_map(|(i, row)| row.iter().enumerate().filter(move |(j, _)| *j > i).map(|(_, &s)| s))
.flat_map(|(i, row)| {
row.iter()
.enumerate()
.filter(move |(j, _)| *j > i)
.map(|(_, &s)| s)
})
.collect();
let mean_sim: f32 = all_sims.iter().sum::<f32>() / all_sims.len().max(1) as f32;
@ -204,8 +210,9 @@ impl TopologyGate {
// Combine metrics
// High mean similarity and low variance = high coherence
// High boundary mass = low coherence
let coherence_score = (mean_sim * 0.5 + (1.0 - variance.sqrt()) * 0.3 + (1.0 - boundary_ratio) * 0.2)
.clamp(0.0, 1.0);
let coherence_score =
(mean_sim * 0.5 + (1.0 - variance.sqrt()) * 0.3 + (1.0 - boundary_ratio) * 0.2)
.clamp(0.0, 1.0);
CoherenceMetrics {
coherence_score,

View file

@ -131,7 +131,11 @@ impl ScopeEnergy {
let (max_edge_energy, hotspot_edge) = edge_energies
.iter()
.max_by(|a, b| a.energy.partial_cmp(&b.energy).unwrap_or(std::cmp::Ordering::Equal))
.max_by(|a, b| {
a.energy
.partial_cmp(&b.energy)
.unwrap_or(std::cmp::Ordering::Equal)
})
.map(|e| (e.energy, Some(e.edge_id.clone())))
.unwrap_or((0.0, None));
@ -289,7 +293,11 @@ impl CoherenceEnergy {
/// Identify the top-k hotspots (highest energy edges)
pub fn hotspots(&self, k: usize) -> Vec<HotspotInfo> {
let mut sorted: Vec<_> = self.edge_energies.values().collect();
sorted.sort_by(|a, b| b.energy.partial_cmp(&a.energy).unwrap_or(std::cmp::Ordering::Equal));
sorted.sort_by(|a, b| {
b.energy
.partial_cmp(&a.energy)
.unwrap_or(std::cmp::Ordering::Equal)
});
sorted
.into_iter()
@ -347,8 +355,8 @@ impl CoherenceEnergy {
let mean = self.average_edge_energy();
// Compute standard deviation
let variance: f32 = energies.iter().map(|e| (e - mean).powi(2)).sum::<f32>()
/ energies.len() as f32;
let variance: f32 =
energies.iter().map(|e| (e - mean).powi(2)).sum::<f32>() / energies.len() as f32;
let std_dev = variance.sqrt();
// Compute median
@ -385,10 +393,7 @@ impl CoherenceEnergy {
.cloned()
.unwrap_or_else(|| "default".to_string());
scope_groups
.entry(scope_id)
.or_default()
.push(edge_energy);
scope_groups.entry(scope_id).or_default().push(edge_energy);
}
// Create scope energies
@ -538,13 +543,21 @@ pub fn compute_residual(projected_source: &[f32], projected_target: &[f32]) -> V
/// Compute residual into pre-allocated buffer (zero allocation)
#[inline]
pub fn compute_residual_into(projected_source: &[f32], projected_target: &[f32], result: &mut [f32]) {
pub fn compute_residual_into(
projected_source: &[f32],
projected_target: &[f32],
result: &mut [f32],
) {
debug_assert_eq!(
projected_source.len(),
projected_target.len(),
"Projected vectors must have same dimension"
);
debug_assert_eq!(result.len(), projected_source.len(), "Result buffer size mismatch");
debug_assert_eq!(
result.len(),
projected_source.len(),
"Result buffer size mismatch"
);
// Unrolled loop for better vectorization
let len = projected_source.len();

View file

@ -29,7 +29,9 @@
//! println!("Total energy: {}", energy.total_energy);
//! ```
use super::energy::{compute_norm_sq, compute_residual, CoherenceEnergy, EdgeEnergy, EdgeId, ScopeId};
use super::energy::{
compute_norm_sq, compute_residual, CoherenceEnergy, EdgeEnergy, EdgeId, ScopeId,
};
use chrono::{DateTime, Utc};
use dashmap::DashMap;
use parking_lot::RwLock;
@ -695,8 +697,9 @@ impl CoherenceEngine {
return Err(CoherenceError::EdgeExists(source, target));
}
let mut edge =
SheafEdge::with_restriction_maps(&edge_id, &source, &target, weight, rho_source, rho_target);
let mut edge = SheafEdge::with_restriction_maps(
&edge_id, &source, &target, weight, rho_source, rho_target,
);
if let Some(s) = scope.clone() {
edge = edge.with_scope(s.clone());
self.edge_scopes.insert(edge_id.clone(), s);
@ -864,11 +867,9 @@ impl CoherenceEngine {
for edge_ref in &edges {
let edge = edge_ref.value();
if let Some(energy) = self.compute_edge_energy_with_buffers(
edge,
&mut source_buf,
&mut target_buf,
) {
if let Some(energy) =
self.compute_edge_energy_with_buffers(edge, &mut source_buf, &mut target_buf)
{
result.insert(edge.id.clone(), energy);
}
}

View file

@ -172,11 +172,15 @@ impl UpdateEvent {
/// Check if this event affects the given edge
pub fn affects_edge(&self, edge_id: &str) -> bool {
match self {
UpdateEvent::NodeUpdated { affected_edges, .. } => affected_edges.contains(&edge_id.to_string()),
UpdateEvent::NodeUpdated { affected_edges, .. } => {
affected_edges.contains(&edge_id.to_string())
}
UpdateEvent::EdgeAdded { edge_id: eid, .. } => eid == edge_id,
UpdateEvent::EdgeRemoved { edge_id: eid, .. } => eid == edge_id,
UpdateEvent::NodeAdded { .. } => false,
UpdateEvent::NodeRemoved { removed_edges, .. } => removed_edges.contains(&edge_id.to_string()),
UpdateEvent::NodeRemoved { removed_edges, .. } => {
removed_edges.contains(&edge_id.to_string())
}
}
}
}
@ -558,15 +562,13 @@ impl<'a> IncrementalEngine<'a> {
// Update cache
for (edge_id, edge_energy) in new_energies {
self.cache.update_edge(
edge_id,
edge_energy.energy,
edge_energy.residual,
);
self.cache
.update_edge(edge_id, edge_energy.energy, edge_energy.residual);
}
// Update fingerprint
self.cache.set_fingerprint(self.engine.current_fingerprint());
self.cache
.set_fingerprint(self.engine.current_fingerprint());
self.cache.total_energy()
}

View file

@ -63,16 +63,15 @@ pub use energy::{
EnergyStatistics, HotspotInfo, ScopeEnergy, ScopeId,
};
pub use engine::{
CoherenceConfig, CoherenceEngine, CoherenceError, NodeState, RestrictionMap, Result,
SheafEdge, SheafNode,
CoherenceConfig, CoherenceEngine, CoherenceError, NodeState, RestrictionMap, Result, SheafEdge,
SheafNode,
};
pub use history::{EnergyHistory, EnergyHistoryConfig, EnergyTrend, TrendDirection};
pub use incremental::{
DeltaResult, IncrementalCache, IncrementalConfig, IncrementalEngine, UpdateEvent,
};
pub use spectral::{
compute_eigenvalues, DriftEvent, DriftSeverity, SpectralAnalyzer, SpectralConfig,
SpectralStats,
compute_eigenvalues, DriftEvent, DriftSeverity, SpectralAnalyzer, SpectralConfig, SpectralStats,
};
// Alias for compatibility

View file

@ -59,8 +59,8 @@ impl Default for SpectralConfig {
Self {
num_eigenvalues: 10,
history_size: 100,
drift_threshold: 0.1, // 10% relative change
severe_threshold: 0.25, // 25% relative change
drift_threshold: 0.1, // 10% relative change
severe_threshold: 0.25, // 25% relative change
min_samples: 3,
smoothing_alpha: 0.3,
}
@ -301,7 +301,8 @@ impl SpectralAnalyzer {
// Compute average pairwise distance
let mut total_distance = 0.0;
for i in 0..recent.len() - 1 {
total_distance += self.spectral_distance(&recent[i].eigenvalues, &recent[i + 1].eigenvalues);
total_distance +=
self.spectral_distance(&recent[i].eigenvalues, &recent[i + 1].eigenvalues);
}
Some(total_distance / window as f32)
@ -391,7 +392,9 @@ impl SpectralAnalyzer {
fn classify_severity(&self, distance: f32, connectivity_change: f32) -> DriftSeverity {
let is_connectivity_loss = connectivity_change < -self.config.drift_threshold;
if distance > self.config.severe_threshold * 2.0 || (is_connectivity_loss && distance > self.config.severe_threshold) {
if distance > self.config.severe_threshold * 2.0
|| (is_connectivity_loss && distance > self.config.severe_threshold)
{
DriftSeverity::Critical
} else if distance > self.config.severe_threshold {
DriftSeverity::Severe
@ -595,11 +598,7 @@ pub fn compute_eigenvalues(laplacian: &[Vec<f32>], k: usize) -> Vec<f32> {
// Compute eigenvalues
let eigen = SymmetricEigen::new(matrix);
let mut eigenvalues: Vec<f32> = eigen
.eigenvalues
.iter()
.map(|&x| x as f32)
.collect();
let mut eigenvalues: Vec<f32> = eigen.eigenvalues.iter().map(|&x| x as f32).collect();
// Sort and take top k
eigenvalues.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));

View file

@ -3,8 +3,8 @@
//! Cocycles are the building blocks of cohomology. A cocycle is a cochain
//! that is in the kernel of the coboundary operator.
use super::simplex::{Cochain, SimplexId, SimplicialComplex};
use super::sheaf::{Sheaf, SheafSection};
use super::simplex::{Cochain, SimplexId, SimplicialComplex};
use crate::substrate::NodeId;
use ndarray::Array1;
use serde::{Deserialize, Serialize};

View file

@ -266,9 +266,7 @@ impl CohomologyComputer {
let (rref, pivot_cols) = self.row_reduce(matrix);
let n_cols = matrix.ncols();
let free_vars: Vec<usize> = (0..n_cols)
.filter(|c| !pivot_cols.contains(c))
.collect();
let free_vars: Vec<usize> = (0..n_cols).filter(|c| !pivot_cols.contains(c)).collect();
for &free_var in &free_vars {
let mut kernel_vec = Array1::zeros(n_cols);
@ -411,10 +409,8 @@ impl CohomologyComputer {
}
// Build index to simplex ID map
let idx_to_simplex: HashMap<usize, SimplexId> = simplex_to_idx
.iter()
.map(|(&id, &idx)| (idx, id))
.collect();
let idx_to_simplex: HashMap<usize, SimplexId> =
simplex_to_idx.iter().map(|(&id, &idx)| (idx, id)).collect();
// If no image, all kernel elements are generators
if image.is_empty() {
@ -486,9 +482,7 @@ impl CohomologyComputer {
/// Compute all cohomology groups up to max_dimension
pub fn compute_all(&mut self) -> Vec<CohomologyGroup> {
let max_dim = self.config.max_dimension.min(self.complex.max_dimension);
(0..=max_dim)
.map(|n| self.compute_cohomology(n))
.collect()
(0..=max_dim).map(|n| self.compute_cohomology(n)).collect()
}
/// Compute Betti numbers

View file

@ -7,8 +7,8 @@
use super::laplacian::{LaplacianConfig, SheafLaplacian};
use super::obstruction::{ObstructionDetector, ObstructionSeverity};
use super::sheaf::SheafSection;
use crate::substrate::SheafGraph;
use crate::substrate::NodeId;
use crate::substrate::SheafGraph;
use ndarray::Array1;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@ -109,9 +109,7 @@ impl DiffusionResult {
/// Check if obstruction was detected
pub fn has_obstruction(&self) -> bool {
self.residual_obstruction
.map(|e| e > 0.01)
.unwrap_or(false)
self.residual_obstruction.map(|e| e > 0.01).unwrap_or(false)
}
/// Get persistent obstructions
@ -188,8 +186,10 @@ impl SheafDiffusion {
// Check if obstruction is persistent
if step > 20 {
let recent_energies = &energy_history[energy_history.len().saturating_sub(10)..];
let avg_recent: f64 = recent_energies.iter().sum::<f64>() / recent_energies.len() as f64;
let recent_energies =
&energy_history[energy_history.len().saturating_sub(10)..];
let avg_recent: f64 =
recent_energies.iter().sum::<f64>() / recent_energies.len() as f64;
indicator.is_persistent = (new_energy - avg_recent).abs() < 0.01 * avg_recent;
}
@ -328,9 +328,7 @@ impl SheafDiffusion {
for node_id in graph.node_ids() {
if let Some(node) = graph.get_node(node_id) {
let values: Vec<f64> = node.state.as_slice().iter()
.map(|&x| x as f64)
.collect();
let values: Vec<f64> = node.state.as_slice().iter().map(|&x| x as f64).collect();
section.set(node_id, Array1::from_vec(values));
}
}
@ -353,7 +351,11 @@ impl SheafDiffusion {
}
/// Compute per-node energies
fn compute_node_energies(&self, graph: &SheafGraph, section: &SheafSection) -> HashMap<NodeId, f64> {
fn compute_node_energies(
&self,
graph: &SheafGraph,
section: &SheafSection,
) -> HashMap<NodeId, f64> {
let mut node_energies: HashMap<NodeId, f64> = HashMap::new();
for node_id in graph.node_ids() {
@ -367,10 +369,9 @@ impl SheafDiffusion {
edge.source
};
if let (Some(this_val), Some(other_val)) = (
section.get(node_id),
section.get(other),
) {
if let (Some(this_val), Some(other_val)) =
(section.get(node_id), section.get(other))
{
let residual = this_val - other_val;
let residual_norm: f64 = residual.iter().map(|x| x * x).sum();
energy += (edge.weight as f64) * residual_norm;
@ -462,12 +463,8 @@ mod tests {
fn test_adaptive_diffusion() {
let graph = SheafGraph::new();
let node1 = SheafNodeBuilder::new()
.state_from_slice(&[5.0])
.build();
let node2 = SheafNodeBuilder::new()
.state_from_slice(&[-5.0])
.build();
let node1 = SheafNodeBuilder::new().state_from_slice(&[5.0]).build();
let node2 = SheafNodeBuilder::new().state_from_slice(&[-5.0]).build();
let id1 = graph.add_node(node1);
let id2 = graph.add_node(node2);

View file

@ -9,8 +9,8 @@
//! - Small eigenvalues indicate near-obstructions
use super::sheaf::{Sheaf, SheafSection};
use crate::substrate::SheafGraph;
use crate::substrate::NodeId;
use crate::substrate::SheafGraph;
use ndarray::{Array1, Array2};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@ -211,25 +211,25 @@ impl SheafLaplacian {
let source_offset = self.vertex_to_offset.get(&source).copied().unwrap_or(0);
let target_offset = self.vertex_to_offset.get(&target).copied().unwrap_or(0);
if let Some(edge) = graph
.edge_ids()
.into_iter()
.find_map(|eid| {
let e = graph.get_edge(eid)?;
if e.source == source && e.target == target {
Some(e)
} else if e.source == target && e.target == source {
Some(e)
} else {
None
}
})
{
let source_dim = self.vertices.iter()
if let Some(edge) = graph.edge_ids().into_iter().find_map(|eid| {
let e = graph.get_edge(eid)?;
if e.source == source && e.target == target {
Some(e)
} else if e.source == target && e.target == source {
Some(e)
} else {
None
}
}) {
let source_dim = self
.vertices
.iter()
.find(|(v, _)| *v == source)
.map(|(_, d)| *d)
.unwrap_or(0);
let target_dim = self.vertices.iter()
let target_dim = self
.vertices
.iter()
.find(|(v, _)| *v == target)
.map(|(_, d)| *d)
.unwrap_or(0);
@ -417,9 +417,7 @@ impl SheafLaplacian {
for (vertex, dim) in &self.vertices {
let offset = self.vertex_to_offset.get(vertex).copied().unwrap_or(0);
let values = Array1::from_iter(
(0..*dim).map(|j| evec[offset + j])
);
let values = Array1::from_iter((0..*dim).map(|j| evec[offset + j]));
cochain.insert(*vertex, values);
}
@ -482,12 +480,8 @@ mod tests {
fn test_laplacian_energy() {
let graph = SheafGraph::new();
let node1 = SheafNodeBuilder::new()
.state_from_slice(&[1.0])
.build();
let node2 = SheafNodeBuilder::new()
.state_from_slice(&[2.0])
.build();
let node1 = SheafNodeBuilder::new().state_from_slice(&[1.0]).build();
let node2 = SheafNodeBuilder::new().state_from_slice(&[2.0]).build();
let id1 = graph.add_node(node1);
let id2 = graph.add_node(node2);
@ -515,15 +509,9 @@ mod tests {
fn test_connected_graph_has_one_zero_eigenvalue() {
let graph = SheafGraph::new();
let node1 = SheafNodeBuilder::new()
.state_from_slice(&[1.0])
.build();
let node2 = SheafNodeBuilder::new()
.state_from_slice(&[1.0])
.build();
let node3 = SheafNodeBuilder::new()
.state_from_slice(&[1.0])
.build();
let node1 = SheafNodeBuilder::new().state_from_slice(&[1.0]).build();
let node2 = SheafNodeBuilder::new().state_from_slice(&[1.0]).build();
let node3 = SheafNodeBuilder::new().state_from_slice(&[1.0]).build();
let id1 = graph.add_node(node1);
let id2 = graph.add_node(node2);

View file

@ -47,22 +47,14 @@ mod obstruction;
mod sheaf;
mod simplex;
pub use cocycle::{Cocycle, CocycleBuilder, Coboundary};
pub use cohomology_group::{
CohomologyGroup, CohomologyComputer, CohomologyConfig, BettiNumbers,
};
pub use diffusion::{
SheafDiffusion, SheafDiffusionConfig, DiffusionResult, ObstructionIndicator,
};
pub use laplacian::{
SheafLaplacian, LaplacianConfig, LaplacianSpectrum, HarmonicRepresentative,
};
pub use cocycle::{Coboundary, Cocycle, CocycleBuilder};
pub use cohomology_group::{BettiNumbers, CohomologyComputer, CohomologyConfig, CohomologyGroup};
pub use diffusion::{DiffusionResult, ObstructionIndicator, SheafDiffusion, SheafDiffusionConfig};
pub use laplacian::{HarmonicRepresentative, LaplacianConfig, LaplacianSpectrum, SheafLaplacian};
pub use neural::{
SheafNeuralLayer, SheafNeuralConfig, SheafConvolution, CohomologyPooling,
Activation, PoolingMethod,
Activation, CohomologyPooling, PoolingMethod, SheafConvolution, SheafNeuralConfig,
SheafNeuralLayer,
};
pub use obstruction::{
ObstructionDetector, Obstruction, ObstructionSeverity, ObstructionReport,
};
pub use sheaf::{Sheaf, SheafBuilder, Stalk, SheafSection, LocalSection};
pub use simplex::{Simplex, SimplexId, SimplicialComplex, Chain, Cochain};
pub use obstruction::{Obstruction, ObstructionDetector, ObstructionReport, ObstructionSeverity};
pub use sheaf::{LocalSection, Sheaf, SheafBuilder, SheafSection, Stalk};
pub use simplex::{Chain, Cochain, Simplex, SimplexId, SimplicialComplex};

View file

@ -5,8 +5,8 @@
use super::laplacian::{LaplacianConfig, SheafLaplacian};
use super::sheaf::{Sheaf, SheafSection};
use crate::substrate::SheafGraph;
use crate::substrate::NodeId;
use crate::substrate::SheafGraph;
use ndarray::{Array1, Array2};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@ -36,7 +36,13 @@ impl Activation {
match self {
Activation::Identity => x,
Activation::ReLU => x.max(0.0),
Activation::LeakyReLU(alpha) => if x > 0.0 { x } else { alpha * x },
Activation::LeakyReLU(alpha) => {
if x > 0.0 {
x
} else {
alpha * x
}
}
Activation::Sigmoid => 1.0 / (1.0 + (-x).exp()),
Activation::Tanh => x.tanh(),
Activation::GELU => {
@ -65,8 +71,20 @@ impl Activation {
pub fn derivative(&self, x: f64) -> f64 {
match self {
Activation::Identity => 1.0,
Activation::ReLU => if x > 0.0 { 1.0 } else { 0.0 },
Activation::LeakyReLU(alpha) => if x > 0.0 { 1.0 } else { *alpha },
Activation::ReLU => {
if x > 0.0 {
1.0
} else {
0.0
}
}
Activation::LeakyReLU(alpha) => {
if x > 0.0 {
1.0
} else {
*alpha
}
}
Activation::Sigmoid => {
let s = self.apply(x);
s * (1.0 - s)
@ -143,10 +161,9 @@ impl SheafNeuralLayer {
let scale = (2.0 / (config.input_dim + config.output_dim) as f64).sqrt();
// Initialize weights with Xavier
let weights = Array2::from_shape_fn(
(config.output_dim, config.input_dim),
|_| rand::random::<f64>() * scale - scale / 2.0,
);
let weights = Array2::from_shape_fn((config.output_dim, config.input_dim), |_| {
rand::random::<f64>() * scale - scale / 2.0
});
let bias = Array1::zeros(config.output_dim);
@ -159,7 +176,11 @@ impl SheafNeuralLayer {
}
/// Create with specific weights
pub fn with_weights(config: SheafNeuralConfig, weights: Array2<f64>, bias: Array1<f64>) -> Self {
pub fn with_weights(
config: SheafNeuralConfig,
weights: Array2<f64>,
bias: Array1<f64>,
) -> Self {
assert_eq!(weights.nrows(), config.output_dim);
assert_eq!(weights.ncols(), config.input_dim);
assert_eq!(bias.len(), config.output_dim);
@ -293,14 +314,12 @@ impl SheafConvolution {
pub fn new(input_dim: usize, output_dim: usize) -> Self {
let scale = (2.0 / (input_dim + output_dim) as f64).sqrt();
let self_weight = Array2::from_shape_fn(
(output_dim, input_dim),
|_| rand::random::<f64>() * scale - scale / 2.0,
);
let neighbor_weight = Array2::from_shape_fn(
(output_dim, input_dim),
|_| rand::random::<f64>() * scale - scale / 2.0,
);
let self_weight = Array2::from_shape_fn((output_dim, input_dim), |_| {
rand::random::<f64>() * scale - scale / 2.0
});
let neighbor_weight = Array2::from_shape_fn((output_dim, input_dim), |_| {
rand::random::<f64>() * scale - scale / 2.0
});
let bias = Array1::zeros(output_dim);
Self {
@ -428,7 +447,12 @@ impl CohomologyPooling {
return Array1::zeros(0);
}
let dim = section.sections.values().next().map(|v| v.len()).unwrap_or(0);
let dim = section
.sections
.values()
.next()
.map(|v| v.len())
.unwrap_or(0);
match self.method {
PoolingMethod::Mean => {
@ -477,10 +501,13 @@ impl CohomologyPooling {
}
PoolingMethod::TopK(k) => {
// Select top k nodes by L2 norm
let mut node_norms: Vec<_> = section.sections.iter()
let mut node_norms: Vec<_> = section
.sections
.iter()
.map(|(id, vec)| (*id, vec.iter().map(|x| x * x).sum::<f64>()))
.collect();
node_norms.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
node_norms
.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
let mut sum = Array1::zeros(dim);
for (node_id, _) in node_norms.into_iter().take(k) {
@ -601,12 +628,8 @@ mod tests {
fn test_pooling() {
let graph = SheafGraph::new();
let node1 = SheafNodeBuilder::new()
.state_from_slice(&[1.0])
.build();
let node2 = SheafNodeBuilder::new()
.state_from_slice(&[3.0])
.build();
let node1 = SheafNodeBuilder::new().state_from_slice(&[1.0]).build();
let node2 = SheafNodeBuilder::new().state_from_slice(&[3.0]).build();
let id1 = graph.add_node(node1);
let id2 = graph.add_node(node2);

View file

@ -7,8 +7,8 @@
use super::cocycle::{Cocycle, SheafCoboundary};
use super::laplacian::{HarmonicRepresentative, LaplacianConfig, SheafLaplacian};
use super::sheaf::{Sheaf, SheafSection};
use crate::substrate::SheafGraph;
use crate::substrate::NodeId;
use crate::substrate::SheafGraph;
use ndarray::Array1;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@ -80,12 +80,7 @@ pub struct Obstruction {
impl Obstruction {
/// Create a new obstruction
pub fn new(
id: u64,
degree: usize,
energy: f64,
severity: ObstructionSeverity,
) -> Self {
pub fn new(id: u64, degree: usize, energy: f64, severity: ObstructionSeverity) -> Self {
Self {
id,
degree,
@ -101,7 +96,8 @@ impl Obstruction {
/// Add edge contribution
pub fn add_edge_contribution(&mut self, source: NodeId, target: NodeId, contribution: f64) {
self.edge_contributions.insert((source, target), contribution);
self.edge_contributions
.insert((source, target), contribution);
}
/// Set hotspots
@ -124,7 +120,9 @@ impl Obstruction {
/// Get top k contributing edges
pub fn top_edges(&self, k: usize) -> Vec<((NodeId, NodeId), f64)> {
let mut edges: Vec<_> = self.edge_contributions.iter()
let mut edges: Vec<_> = self
.edge_contributions
.iter()
.map(|(&e, &c)| (e, c))
.collect();
edges.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
@ -263,10 +261,9 @@ impl ObstructionDetector {
let mut edge_energies: HashMap<(NodeId, NodeId), f64> = HashMap::new();
for edge_id in graph.edge_ids() {
if let Some(edge) = graph.get_edge(edge_id) {
if let (Some(source_node), Some(target_node)) = (
graph.get_node(edge.source),
graph.get_node(edge.target),
) {
if let (Some(source_node), Some(target_node)) =
(graph.get_node(edge.source), graph.get_node(edge.target))
{
let residual = edge.weighted_residual_energy(
source_node.state.as_slice(),
target_node.state.as_slice(),
@ -325,9 +322,7 @@ impl ObstructionDetector {
for node_id in graph.node_ids() {
if let Some(node) = graph.get_node(node_id) {
let values: Vec<f64> = node.state.as_slice().iter()
.map(|&x| x as f64)
.collect();
let values: Vec<f64> = node.state.as_slice().iter().map(|&x| x as f64).collect();
section.set(node_id, Array1::from_vec(values));
}
}
@ -372,7 +367,11 @@ impl ObstructionDetector {
ObstructionSeverity::Moderate => {
recommendations.push(format!(
"Moderate obstruction. Focus on hotspot nodes: {:?}",
obs.hotspots.iter().take(3).map(|(n, _)| n).collect::<Vec<_>>()
obs.hotspots
.iter()
.take(3)
.map(|(n, _)| n)
.collect::<Vec<_>>()
));
}
ObstructionSeverity::Severe | ObstructionSeverity::Critical => {
@ -380,9 +379,8 @@ impl ObstructionDetector {
"Severe obstruction with energy {:.4}. Immediate review required.",
obs.energy
));
recommendations.push(
"Consider isolating incoherent region using MinCut".to_string()
);
recommendations
.push("Consider isolating incoherent region using MinCut".to_string());
}
_ => {}
}
@ -390,7 +388,7 @@ impl ObstructionDetector {
if report.spectral_gap.is_some_and(|g| g < 0.1) {
recommendations.push(
"Small spectral gap indicates near-obstruction. Monitor for drift.".to_string()
"Small spectral gap indicates near-obstruction. Monitor for drift.".to_string(),
);
}
@ -495,15 +493,9 @@ mod tests {
fn test_obstruction_hotspots() {
let graph = SheafGraph::new();
let node1 = SheafNodeBuilder::new()
.state_from_slice(&[1.0])
.build();
let node2 = SheafNodeBuilder::new()
.state_from_slice(&[5.0])
.build();
let node3 = SheafNodeBuilder::new()
.state_from_slice(&[1.5])
.build();
let node1 = SheafNodeBuilder::new().state_from_slice(&[1.0]).build();
let node2 = SheafNodeBuilder::new().state_from_slice(&[5.0]).build();
let node3 = SheafNodeBuilder::new().state_from_slice(&[1.5]).build();
let id1 = graph.add_node(node1);
let id2 = graph.add_node(node2);

View file

@ -6,8 +6,8 @@
//!
//! This is the foundational structure for cohomology computation.
use crate::substrate::{RestrictionMap, SheafGraph};
use crate::substrate::NodeId;
use crate::substrate::{RestrictionMap, SheafGraph};
use ndarray::{Array1, Array2};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@ -222,7 +222,12 @@ impl Sheaf {
}
/// Apply restriction map from source to target
pub fn restrict(&self, source: NodeId, target: NodeId, value: &Array1<f64>) -> Option<Array1<f64>> {
pub fn restrict(
&self,
source: NodeId,
target: NodeId,
value: &Array1<f64>,
) -> Option<Array1<f64>> {
self.restriction_maps
.get(&(source, target))
.map(|rho| rho(value))
@ -338,9 +343,8 @@ impl SheafBuilder {
target: NodeId,
indices: Vec<usize>,
) -> Self {
let proj_fn: RestrictionFn = Arc::new(move |v: &Array1<f64>| {
Array1::from_iter(indices.iter().map(|&i| v[i]))
});
let proj_fn: RestrictionFn =
Arc::new(move |v: &Array1<f64>| Array1::from_iter(indices.iter().map(|&i| v[i])));
self.sheaf.add_restriction(source, target, proj_fn);
self
}

View file

@ -379,7 +379,12 @@ impl Chain {
if coefficient.abs() > 1e-10 {
*self.coefficients.entry(id).or_insert(0.0) += coefficient;
// Remove if coefficient is now essentially zero
if self.coefficients.get(&id).map(|c| c.abs() < 1e-10).unwrap_or(false) {
if self
.coefficients
.get(&id)
.map(|c| c.abs() < 1e-10)
.unwrap_or(false)
{
self.coefficients.remove(&id);
}
}
@ -394,7 +399,10 @@ impl Chain {
/// Add another chain to this one
pub fn add(&mut self, other: &Chain) {
assert_eq!(self.dimension, other.dimension, "Chain dimensions must match");
assert_eq!(
self.dimension, other.dimension,
"Chain dimensions must match"
);
for (&id, &coeff) in &other.coefficients {
self.add_simplex(id, coeff);
}
@ -407,7 +415,11 @@ impl Chain {
/// L2 norm of the chain
pub fn norm(&self) -> f64 {
self.coefficients.values().map(|c| c * c).sum::<f64>().sqrt()
self.coefficients
.values()
.map(|c| c * c)
.sum::<f64>()
.sqrt()
}
}
@ -462,7 +474,10 @@ impl Cochain {
/// Add another cochain to this one
pub fn add(&mut self, other: &Cochain) {
assert_eq!(self.dimension, other.dimension, "Cochain dimensions must match");
assert_eq!(
self.dimension, other.dimension,
"Cochain dimensions must match"
);
for (&id, &value) in &other.values {
let new_val = self.get(id) + value;
self.set(id, new_val);

View file

@ -2,36 +2,22 @@
//!
//! Wraps Raft consensus for coherence state replication.
use super::{DistributedCoherenceConfig, DistributedError, Result};
use super::config::NodeRole;
use super::{DistributedCoherenceConfig, DistributedError, Result};
/// Command types for coherence state machine
#[derive(Debug, Clone)]
pub enum CoherenceCommand {
/// Update energy for an edge
UpdateEnergy {
edge_id: (u64, u64),
energy: f32,
},
UpdateEnergy { edge_id: (u64, u64), energy: f32 },
/// Set node state vector
SetNodeState {
node_id: u64,
state: Vec<f32>,
},
SetNodeState { node_id: u64, state: Vec<f32> },
/// Record coherence checkpoint
Checkpoint {
total_energy: f32,
timestamp: u64,
},
Checkpoint { total_energy: f32, timestamp: u64 },
/// Mark region as incoherent
MarkIncoherent {
region_id: u64,
nodes: Vec<u64>,
},
MarkIncoherent { region_id: u64, nodes: Vec<u64> },
/// Clear incoherence flag
ClearIncoherent {
region_id: u64,
},
ClearIncoherent { region_id: u64 },
}
impl CoherenceCommand {
@ -54,7 +40,10 @@ impl CoherenceCommand {
bytes.extend(v.to_le_bytes());
}
}
Self::Checkpoint { total_energy, timestamp } => {
Self::Checkpoint {
total_energy,
timestamp,
} => {
bytes.push(2);
bytes.extend(total_energy.to_le_bytes());
bytes.extend(timestamp.to_le_bytes());
@ -111,7 +100,10 @@ impl CoherenceCommand {
2 if data.len() >= 12 => {
let total_energy = f32::from_le_bytes(data[0..4].try_into().ok()?);
let timestamp = u64::from_le_bytes(data[4..12].try_into().ok()?);
Some(Self::Checkpoint { total_energy, timestamp })
Some(Self::Checkpoint {
total_energy,
timestamp,
})
}
3 if data.len() >= 12 => {
let region_id = u64::from_le_bytes(data[0..8].try_into().ok()?);
@ -169,9 +161,17 @@ impl RaftAdapter {
pub fn new(config: DistributedCoherenceConfig) -> Self {
let is_leader = config.is_single_node();
Self {
role: if is_leader { NodeRole::Leader } else { NodeRole::Follower },
role: if is_leader {
NodeRole::Leader
} else {
NodeRole::Follower
},
current_term: 1,
current_leader: if is_leader { Some(config.node_id.clone()) } else { None },
current_leader: if is_leader {
Some(config.node_id.clone())
} else {
None
},
log_index: 0,
pending_commands: Vec::new(),
config,
@ -231,7 +231,10 @@ impl RaftAdapter {
/// Record checkpoint
pub fn checkpoint(&mut self, total_energy: f32, timestamp: u64) -> Result<CommandResult> {
let command = CoherenceCommand::Checkpoint { total_energy, timestamp };
let command = CoherenceCommand::Checkpoint {
total_energy,
timestamp,
};
self.submit_command(command)
}
@ -358,7 +361,11 @@ mod tests {
fn test_not_leader_error() {
let config = DistributedCoherenceConfig {
node_id: "node1".to_string(),
cluster_members: vec!["node1".to_string(), "node2".to_string(), "node3".to_string()],
cluster_members: vec![
"node1".to_string(),
"node2".to_string(),
"node3".to_string(),
],
..Default::default()
};
let mut adapter = RaftAdapter::new(config);

View file

@ -80,7 +80,10 @@ impl DistributedCoherenceConfig {
/// Create configuration for a 3-node cluster
pub fn three_node_cluster(node_id: &str, members: Vec<String>) -> Self {
assert!(members.len() >= 3, "Need at least 3 members for 3-node cluster");
assert!(
members.len() >= 3,
"Need at least 3 members for 3-node cluster"
);
Self {
node_id: node_id.to_string(),
cluster_members: members,
@ -91,7 +94,10 @@ impl DistributedCoherenceConfig {
/// Create configuration for a 5-node cluster
pub fn five_node_cluster(node_id: &str, members: Vec<String>) -> Self {
assert!(members.len() >= 5, "Need at least 5 members for 5-node cluster");
assert!(
members.len() >= 5,
"Need at least 5 members for 5-node cluster"
);
Self {
node_id: node_id.to_string(),
cluster_members: members,
@ -141,7 +147,9 @@ impl DistributedCoherenceConfig {
/// Get number of tolerable failures
pub fn max_failures(&self) -> usize {
self.cluster_members.len().saturating_sub(self.quorum_size())
self.cluster_members
.len()
.saturating_sub(self.quorum_size())
}
}

View file

@ -134,7 +134,12 @@ impl DistributedCoherence {
/// Update energy for an edge
///
/// This operation goes through Raft consensus and is replicated to all nodes.
pub fn update_energy(&mut self, source: u64, target: u64, energy: f32) -> Result<CommandResult> {
pub fn update_energy(
&mut self,
source: u64,
target: u64,
energy: f32,
) -> Result<CommandResult> {
let result = self.raft.update_energy((source, target), energy)?;
// Apply to local state machine

View file

@ -174,11 +174,14 @@ impl CoherenceStateMachine {
fn apply_set_node_state(&mut self, node_id: u64, state: Vec<f32>) -> ApplyResult {
let truncated_state: Vec<f32> = state.into_iter().take(self.dimension).collect();
let node = self.node_states.entry(node_id).or_insert_with(|| NodeState {
node_id,
state: vec![0.0; self.dimension],
last_update: 0,
});
let node = self
.node_states
.entry(node_id)
.or_insert_with(|| NodeState {
node_id,
state: vec![0.0; self.dimension],
last_update: 0,
});
node.state = truncated_state;
node.last_update = self.applied_index;
@ -192,7 +195,11 @@ impl CoherenceStateMachine {
total_energy,
timestamp,
num_edges: self.edge_energies.len(),
num_incoherent: self.incoherent_regions.values().filter(|r| r.active).count(),
num_incoherent: self
.incoherent_regions
.values()
.filter(|r| r.active)
.count(),
};
self.checkpoints.push(checkpoint.clone());
@ -252,7 +259,10 @@ impl CoherenceStateMachine {
/// Get number of incoherent regions
pub fn num_incoherent_regions(&self) -> usize {
self.incoherent_regions.values().filter(|r| r.active).count()
self.incoherent_regions
.values()
.filter(|r| r.active)
.count()
}
/// Get all incoherent node IDs
@ -456,7 +466,10 @@ mod tests {
edge.update(1.4);
let trend = edge.trend();
assert!(trend > 0.0, "Trend should be positive for increasing energy");
assert!(
trend > 0.0,
"Trend should be positive for increasing energy"
);
}
#[test]

View file

@ -161,7 +161,12 @@ pub struct ActionImpact {
impl ActionImpact {
/// Create a new impact assessment.
pub const fn new(cost: f32, reversibility: f32, blast_radius: f32, latency_sensitivity: f32) -> Self {
pub const fn new(
cost: f32,
reversibility: f32,
blast_radius: f32,
latency_sensitivity: f32,
) -> Self {
Self {
cost,
reversibility,
@ -209,11 +214,7 @@ impl ActionImpact {
self.latency_sensitivity,
];
scores
.iter()
.zip(weights.iter())
.map(|(s, w)| s * w)
.sum()
scores.iter().zip(weights.iter()).map(|(s, w)| s * w).sum()
}
/// Whether this action should be considered high-risk.
@ -260,7 +261,11 @@ pub struct ActionMetadata {
impl ActionMetadata {
/// Create new metadata with required fields.
pub fn new(action_type: impl Into<String>, description: impl Into<String>, actor_id: impl Into<String>) -> Self {
pub fn new(
action_type: impl Into<String>,
description: impl Into<String>,
actor_id: impl Into<String>,
) -> Self {
Self {
id: ActionId::new(),
action_type: action_type.into(),

View file

@ -290,7 +290,10 @@ impl ActionExecutor {
let mut stats = self.stats.write();
stats.total_denied += 1;
let reason = decision.reason.clone().unwrap_or_else(|| "Gate denied".to_string());
let reason = decision
.reason
.clone()
.unwrap_or_else(|| "Gate denied".to_string());
return ExecutionResult {
result: Err(ActionError::Denied(reason)),
@ -313,15 +316,17 @@ impl ActionExecutor {
"Action queued for human review"
);
self.queue_for_human_review(action.metadata().id.clone(), witness.clone(), energy.clone());
self.queue_for_human_review(
action.metadata().id.clone(),
witness.clone(),
energy.clone(),
);
let mut stats = self.stats.write();
stats.total_allowed += 1;
return ExecutionResult {
result: Err(ActionError::Denied(
"Queued for human review".to_string(),
)),
result: Err(ActionError::Denied("Queued for human review".to_string())),
witness,
decision,
stats: ExecutionStats {
@ -473,9 +478,7 @@ impl ActionExecutor {
let mut queue = self.human_queue.write();
if queue.len() >= self.config.max_human_queue {
warn!(
"Human review queue full, dropping oldest item"
);
warn!("Human review queue full, dropping oldest item");
queue.pop_front();
}
@ -522,12 +525,7 @@ impl ActionExecutor {
/// Get recent witnesses.
pub fn recent_witnesses(&self, limit: usize) -> Vec<WitnessRecord> {
let witnesses = self.witnesses.read();
witnesses
.iter()
.rev()
.take(limit)
.cloned()
.collect()
witnesses.iter().rev().take(limit).cloned().collect()
}
/// Get a witness by ID.
@ -619,7 +617,12 @@ impl ActionResultBuilder {
/// Build the result.
pub fn build(self) -> ActionResult {
if self.success {
ActionResult::success(self.action_id, self.duration_us, self.lane, self.retry_count)
ActionResult::success(
self.action_id,
self.duration_us,
self.lane,
self.retry_count,
)
} else {
ActionResult::failure(
self.action_id,
@ -690,7 +693,9 @@ mod tests {
fn execute(&self, _ctx: &ExecutionContext) -> Result<(), ActionError> {
self.execute_count.fetch_add(1, Ordering::SeqCst);
if self.should_fail {
Err(ActionError::ExecutionFailed("Simulated failure".to_string()))
Err(ActionError::ExecutionFailed(
"Simulated failure".to_string(),
))
} else {
Ok(())
}
@ -829,7 +834,10 @@ mod tests {
executor.execute(&action, &energy);
// Stats should be shared
assert_eq!(executor.stats().total_submitted, executor2.stats().total_submitted);
assert_eq!(
executor.stats().total_submitted,
executor2.stats().total_submitted
);
}
#[test]

View file

@ -143,7 +143,10 @@ impl EnergySnapshot {
let mut fingerprint = [0u8; 32];
let hash_input = format!(
"{}:{}:{}:{}",
total_energy, scope_energy, scope.as_str(), timestamp_ms
total_energy,
scope_energy,
scope.as_str(),
timestamp_ms
);
let hash = blake3::hash(hash_input.as_bytes());
fingerprint.copy_from_slice(hash.as_bytes());
@ -344,12 +347,7 @@ impl EnergyHistory {
}
/// Check if energy has been above threshold for the given duration.
pub fn is_above_threshold(
&self,
scope: &ScopeId,
threshold: f32,
duration: Duration,
) -> bool {
pub fn is_above_threshold(&self, scope: &ScopeId, threshold: f32, duration: Duration) -> bool {
let history = match self.histories.get(scope) {
Some(h) => h,
None => return false,
@ -519,11 +517,9 @@ impl CoherenceGate {
}
// Check for persistent incoherence
let persistent = self.history.is_above_threshold(
scope,
self.thresholds.reflex,
self.persistence_window,
);
let persistent =
self.history
.is_above_threshold(scope, self.thresholds.reflex, self.persistence_window);
let escalation = if persistent && lane < ComputeLane::Heavy {
// Persistent incoherence requires at least Heavy lane

View file

@ -52,10 +52,10 @@ impl ComputeLane {
#[inline]
pub const fn latency_budget_us(&self) -> u64 {
match self {
ComputeLane::Reflex => 1_000, // 1ms
ComputeLane::Retrieval => 10_000, // 10ms
ComputeLane::Heavy => 100_000, // 100ms
ComputeLane::Human => u64::MAX, // No limit (async)
ComputeLane::Reflex => 1_000, // 1ms
ComputeLane::Retrieval => 10_000, // 10ms
ComputeLane::Heavy => 100_000, // 100ms
ComputeLane::Human => u64::MAX, // No limit (async)
}
}
@ -381,7 +381,10 @@ impl EscalationReason {
/// Is this an external trigger?
pub fn is_external(&self) -> bool {
matches!(self, Self::ExternalTrigger { .. } | Self::SystemOverride { .. })
matches!(
self,
Self::ExternalTrigger { .. } | Self::SystemOverride { .. }
)
}
}
@ -491,10 +494,7 @@ mod tests {
#[test]
fn test_lane_escalation() {
assert_eq!(
ComputeLane::Reflex.escalate(),
Some(ComputeLane::Retrieval)
);
assert_eq!(ComputeLane::Reflex.escalate(), Some(ComputeLane::Retrieval));
assert_eq!(ComputeLane::Retrieval.escalate(), Some(ComputeLane::Heavy));
assert_eq!(ComputeLane::Heavy.escalate(), Some(ComputeLane::Human));
assert_eq!(ComputeLane::Human.escalate(), None);

View file

@ -80,31 +80,29 @@ pub mod ladder;
// Re-export primary types for convenient access
pub use action::{
Action, ActionError, ActionId, ActionImpact, ActionMetadata, ActionResult,
BoxedAction, ExecutionContext, ScopeId,
Action, ActionError, ActionId, ActionImpact, ActionMetadata, ActionResult, BoxedAction,
ExecutionContext, ScopeId,
};
pub use gate::{
CoherenceGate, EnergyHistory, EnergySnapshot, GateDecision,
PolicyBundleRef, WitnessId, WitnessRecord,
CoherenceGate, EnergyHistory, EnergySnapshot, GateDecision, PolicyBundleRef, WitnessId,
WitnessRecord,
};
pub use ladder::{
ComputeLane, EscalationReason, LaneThresholds, LaneTransition, ThresholdError,
};
pub use ladder::{ComputeLane, EscalationReason, LaneThresholds, LaneTransition, ThresholdError};
pub use executor::{
ActionExecutor, ActionResultBuilder, ExecutionResult, ExecutionStats,
ExecutorConfig, ExecutorStats, HumanReviewItem,
ActionExecutor, ActionResultBuilder, ExecutionResult, ExecutionStats, ExecutorConfig,
ExecutorStats, HumanReviewItem,
};
/// Prelude module for convenient imports.
pub mod prelude {
pub use super::{
Action, ActionError, ActionExecutor, ActionId, ActionImpact, ActionMetadata,
ActionResult, CoherenceGate, ComputeLane, EnergySnapshot, EscalationReason,
ExecutionContext, ExecutionResult, ExecutorConfig, GateDecision, LaneThresholds,
PolicyBundleRef, ScopeId, WitnessId, WitnessRecord,
Action, ActionError, ActionExecutor, ActionId, ActionImpact, ActionMetadata, ActionResult,
CoherenceGate, ComputeLane, EnergySnapshot, EscalationReason, ExecutionContext,
ExecutionResult, ExecutorConfig, GateDecision, LaneThresholds, PolicyBundleRef, ScopeId,
WitnessId, WitnessRecord,
};
}

View file

@ -24,8 +24,8 @@ pub use policy::{
};
pub use witness::{
ComputeLane as WitnessComputeLane, EnergySnapshot, GateDecision,
WitnessChainError, WitnessError, WitnessId, WitnessRecord,
ComputeLane as WitnessComputeLane, EnergySnapshot, GateDecision, WitnessChainError,
WitnessError, WitnessId, WitnessRecord,
};
pub use lineage::{EntityRef, LineageError, LineageId, LineageRecord, Operation};

View file

@ -610,7 +610,12 @@ impl GpuBuffer {
}
/// Create a new storage buffer with initial data (for dispatch compatibility)
pub fn new_storage<T: Pod>(device: &Device, queue: &Queue, data: &[T], read_write: bool) -> GpuResult<Self> {
pub fn new_storage<T: Pod>(
device: &Device,
queue: &Queue,
data: &[T],
read_write: bool,
) -> GpuResult<Self> {
let usage = if read_write {
BufferUsage::Residuals
} else {
@ -620,7 +625,11 @@ impl GpuBuffer {
}
/// Create a new uninitialized storage buffer
pub fn new_storage_uninit<T: Pod>(device: &Device, count: usize, read_write: bool) -> GpuResult<Self> {
pub fn new_storage_uninit<T: Pod>(
device: &Device,
count: usize,
read_write: bool,
) -> GpuResult<Self> {
let size = count * std::mem::size_of::<T>();
let usage = if read_write {
BufferUsage::Residuals
@ -632,7 +641,13 @@ impl GpuBuffer {
/// Create a new uniform buffer with data
pub fn new_uniform<T: Pod>(device: &Device, queue: &Queue, data: &T) -> GpuResult<Self> {
Self::new_with_data(device, queue, std::slice::from_ref(data), BufferUsage::Uniforms, "uniform_buffer")
Self::new_with_data(
device,
queue,
std::slice::from_ref(data),
BufferUsage::Uniforms,
"uniform_buffer",
)
}
}

View file

@ -66,7 +66,10 @@ impl GpuDevice {
gles_minor_version: wgpu::Gles3MinorVersion::default(),
});
debug!("Created wgpu instance with backends: {:?}", options.backends);
debug!(
"Created wgpu instance with backends: {:?}",
options.backends
);
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
@ -182,12 +185,13 @@ impl GpuDevice {
/// This is useful when you need to ensure GPU work has completed
/// before continuing on the CPU.
pub fn poll(&self, wait: bool) -> bool {
self.device.poll(if wait {
wgpu::Maintain::Wait
} else {
wgpu::Maintain::Poll
})
.is_queue_empty()
self.device
.poll(if wait {
wgpu::Maintain::Wait
} else {
wgpu::Maintain::Poll
})
.is_queue_empty()
}
/// Submit a command buffer to the queue
@ -265,7 +269,10 @@ mod tests {
#[test]
fn test_device_options_default() {
let options = GpuDeviceOptions::default();
assert_eq!(options.power_preference, wgpu::PowerPreference::HighPerformance);
assert_eq!(
options.power_preference,
wgpu::PowerPreference::HighPerformance
);
assert!(!options.force_fallback);
}

View file

@ -152,9 +152,7 @@ impl GpuDispatcher {
let mut encoder = self
.device
.device()
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some(label),
});
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some(label) });
{
let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
@ -210,9 +208,7 @@ impl GpuDispatcher {
let mut encoder = self
.device
.device()
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some(label),
});
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some(label) });
{
let mut pass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor {
@ -261,14 +257,16 @@ impl GpuDispatcher {
}
let label = config.label.as_deref().unwrap_or("dispatch_chain");
debug!("Dispatching chain '{}' with {} kernels", label, dispatches.len());
debug!(
"Dispatching chain '{}' with {} kernels",
label,
dispatches.len()
);
let mut encoder = self
.device
.device()
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some(label),
});
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some(label) });
for (i, (pipeline, bind_group, workgroups)) in dispatches.iter().enumerate() {
trace!(

View file

@ -6,12 +6,12 @@
use super::buffer::{BufferUsage, GpuBufferManager, GpuEdge, GpuParams, GpuRestrictionMap};
use super::error::{GpuError, GpuResult};
use super::kernels::{
ComputeEnergyKernel, ComputeResidualsKernel, EnergyParams,
SheafAttentionKernel, TokenRoutingKernel,
ComputeEnergyKernel, ComputeResidualsKernel, EnergyParams, SheafAttentionKernel,
TokenRoutingKernel,
};
use crate::coherence::{CoherenceEnergy as CpuCoherenceEnergy, EdgeEnergy};
use crate::substrate::restriction::MatrixStorage;
use crate::substrate::{SheafGraph, NodeId, EdgeId};
use crate::substrate::{EdgeId, NodeId, SheafGraph};
use chrono::Utc;
use std::collections::HashMap;
@ -312,17 +312,13 @@ impl GpuCoherenceEngine {
// Convert restriction maps
let rho_source_idx = restriction_maps.len() as u32;
let gpu_rho_source = Self::convert_restriction_map(
&edge.rho_source,
&mut restriction_data,
);
let gpu_rho_source =
Self::convert_restriction_map(&edge.rho_source, &mut restriction_data);
restriction_maps.push(gpu_rho_source);
let rho_target_idx = restriction_maps.len() as u32;
let gpu_rho_target = Self::convert_restriction_map(
&edge.rho_target,
&mut restriction_data,
);
let gpu_rho_target =
Self::convert_restriction_map(&edge.rho_target, &mut restriction_data);
restriction_maps.push(gpu_rho_target);
edges.push(GpuEdge {
@ -349,11 +345,8 @@ impl GpuCoherenceEngine {
"node_states",
)?;
self.buffer_manager.allocate_with_data(
&edges,
BufferUsage::EdgeData,
"edges",
)?;
self.buffer_manager
.allocate_with_data(&edges, BufferUsage::EdgeData, "edges")?;
self.buffer_manager.allocate_with_data(
&restriction_maps,
@ -368,21 +361,19 @@ impl GpuCoherenceEngine {
)?;
// Allocate output buffers
let max_comparison_dim = edges.iter().map(|e| e.comparison_dim).max().unwrap_or(state_dim);
let max_comparison_dim = edges
.iter()
.map(|e| e.comparison_dim)
.max()
.unwrap_or(state_dim);
let residuals_size = (num_edges * max_comparison_dim) as usize * std::mem::size_of::<f32>();
let energies_size = num_edges as usize * std::mem::size_of::<f32>();
self.buffer_manager.allocate(
residuals_size,
BufferUsage::Residuals,
"residuals",
)?;
self.buffer_manager
.allocate(residuals_size, BufferUsage::Residuals, "residuals")?;
self.buffer_manager.allocate(
energies_size,
BufferUsage::Energies,
"edge_energies",
)?;
self.buffer_manager
.allocate(energies_size, BufferUsage::Energies, "edge_energies")?;
// Pre-allocate computation buffers to eliminate per-frame allocations
let num_workgroups = ComputeEnergyKernel::workgroup_count(num_edges);
@ -407,7 +398,9 @@ impl GpuCoherenceEngine {
let partial_sums_buffer = self.device.create_buffer(&wgpu::BufferDescriptor {
label: Some("partial_sums_preallocated"),
size: ((num_workgroups as usize).max(1) * std::mem::size_of::<f32>()) as u64,
usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::COPY_DST,
usage: wgpu::BufferUsages::STORAGE
| wgpu::BufferUsages::COPY_SRC
| wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});
@ -423,7 +416,9 @@ impl GpuCoherenceEngine {
let total_energy_buffer = self.device.create_buffer(&wgpu::BufferDescriptor {
label: Some("total_energy_preallocated"),
size: std::mem::size_of::<f32>() as u64,
usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_SRC | wgpu::BufferUsages::COPY_DST,
usage: wgpu::BufferUsages::STORAGE
| wgpu::BufferUsages::COPY_SRC
| wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false,
});
@ -497,7 +492,9 @@ impl GpuCoherenceEngine {
data.extend(csr.values.iter().cloned());
(3, csr.values.len() as u32)
}
MatrixStorage::Dense { data: matrix_data, .. } => {
MatrixStorage::Dense {
data: matrix_data, ..
} => {
data.extend(matrix_data.iter().cloned());
(3, matrix_data.len() as u32)
}
@ -518,7 +515,9 @@ impl GpuCoherenceEngine {
pub async fn compute_energy(&mut self) -> GpuResult<GpuCoherenceEnergy> {
let start = std::time::Instant::now();
let graph_data = self.graph_data.as_ref()
let graph_data = self
.graph_data
.as_ref()
.ok_or_else(|| GpuError::Internal("Graph not uploaded".into()))?;
let num_edges = graph_data.num_edges;
@ -535,27 +534,44 @@ impl GpuCoherenceEngine {
threshold_lane2: self.config.threshold_lane2,
store_residuals: 1, // Store residuals by default for gradient computation
};
self.queue.write_buffer(&graph_data.params_buffer, 0, bytemuck::bytes_of(&params));
self.queue
.write_buffer(&graph_data.params_buffer, 0, bytemuck::bytes_of(&params));
// Write energy params to pre-allocated buffer (no allocation)
let energy_params = EnergyParams {
num_elements: num_edges,
_padding: [0; 7],
};
self.queue.write_buffer(&graph_data.energy_params_buffer, 0, bytemuck::bytes_of(&energy_params));
self.queue.write_buffer(
&graph_data.energy_params_buffer,
0,
bytemuck::bytes_of(&energy_params),
);
// Get managed buffers for bind group creation
let node_states_buf = self.buffer_manager.get("node_states")
let node_states_buf = self
.buffer_manager
.get("node_states")
.ok_or_else(|| GpuError::Internal("Node states buffer not found".into()))?;
let edges_buf = self.buffer_manager.get("edges")
let edges_buf = self
.buffer_manager
.get("edges")
.ok_or_else(|| GpuError::Internal("Edges buffer not found".into()))?;
let restriction_maps_buf = self.buffer_manager.get("restriction_maps")
let restriction_maps_buf = self
.buffer_manager
.get("restriction_maps")
.ok_or_else(|| GpuError::Internal("Restriction maps buffer not found".into()))?;
let restriction_data_buf = self.buffer_manager.get("restriction_data")
let restriction_data_buf = self
.buffer_manager
.get("restriction_data")
.ok_or_else(|| GpuError::Internal("Restriction data buffer not found".into()))?;
let residuals_buf = self.buffer_manager.get("residuals")
let residuals_buf = self
.buffer_manager
.get("residuals")
.ok_or_else(|| GpuError::Internal("Residuals buffer not found".into()))?;
let energies_buf = self.buffer_manager.get("edge_energies")
let energies_buf = self
.buffer_manager
.get("edge_energies")
.ok_or_else(|| GpuError::Internal("Edge energies buffer not found".into()))?;
// Create bind group for residuals kernel using pre-allocated params buffer
@ -579,9 +595,11 @@ impl GpuCoherenceEngine {
);
// Create command encoder
let mut encoder = self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("compute_energy_encoder"),
});
let mut encoder = self
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
label: Some("compute_energy_encoder"),
});
// Dispatch residuals computation
{
@ -618,7 +636,11 @@ impl GpuCoherenceEngine {
num_elements: num_workgroups,
_padding: [0; 7],
};
self.queue.write_buffer(&graph_data.final_params_buffer, 0, bytemuck::bytes_of(&final_params));
self.queue.write_buffer(
&graph_data.final_params_buffer,
0,
bytemuck::bytes_of(&final_params),
);
let final_bind_group = self.energy_kernel.create_bind_group_raw(
&self.device,
@ -670,8 +692,14 @@ impl GpuCoherenceEngine {
self.queue.submit(std::iter::once(encoder.finish()));
// Read back results from pre-allocated staging buffers
let edge_energies = Self::read_buffer_f32(&self.device, &graph_data.energies_staging, num_edges as usize).await?;
let total_energy = Self::read_buffer_f32(&self.device, &graph_data.total_staging, 1).await?[0];
let edge_energies = Self::read_buffer_f32(
&self.device,
&graph_data.energies_staging,
num_edges as usize,
)
.await?;
let total_energy =
Self::read_buffer_f32(&self.device, &graph_data.total_staging, 1).await?[0];
let compute_time_us = start.elapsed().as_micros() as u64;
@ -710,8 +738,8 @@ impl GpuCoherenceEngine {
.map_err(|e| GpuError::BufferRead(e.to_string()))?;
let data = buffer_slice.get_mapped_range();
let result: Vec<f32> = bytemuck::cast_slice(&data[..count * std::mem::size_of::<f32>()])
.to_vec();
let result: Vec<f32> =
bytemuck::cast_slice(&data[..count * std::mem::size_of::<f32>()]).to_vec();
drop(data);
buffer.unmap();

View file

@ -97,17 +97,19 @@ mod kernels;
mod pipeline;
// Core exports
pub use buffer::{BufferUsage, GpuBuffer, GpuBufferManager, GpuBufferPool, BufferUsageFlags, BufferKey};
pub use buffer::{
BufferKey, BufferUsage, BufferUsageFlags, GpuBuffer, GpuBufferManager, GpuBufferPool,
};
pub use device::{GpuDevice, GpuDeviceInfo, GpuDeviceOptions};
pub use dispatch::{DispatchConfig, GpuDispatcher, DispatchBuilder};
pub use dispatch::{DispatchBuilder, DispatchConfig, GpuDispatcher};
pub use error::{GpuError, GpuResult};
pub use pipeline::{BindingDesc, BindingType, ComputePipeline, PipelineCache};
// Re-export buffer types
pub use buffer::{GpuNodeState, GpuEdge, GpuRestrictionMap, GpuParams};
pub use buffer::{GpuEdge, GpuNodeState, GpuParams, GpuRestrictionMap};
// Re-export engine types
pub use engine::{GpuCoherenceEngine, GpuConfig, GpuCapabilities, GpuCoherenceEnergy};
pub use engine::{GpuCapabilities, GpuCoherenceEnergy, GpuCoherenceEngine, GpuConfig};
/// Synchronous API for GPU coherence engine (uses pollster)
pub mod sync {
@ -116,8 +118,8 @@ pub mod sync {
// Re-export kernel types
pub use kernels::{
ComputeResidualsKernel, ComputeEnergyKernel, SheafAttentionKernel, TokenRoutingKernel,
AttentionWeight, Token, RoutingDecision, LaneStats, EnergyParams,
AttentionWeight, ComputeEnergyKernel, ComputeResidualsKernel, EnergyParams, LaneStats,
RoutingDecision, SheafAttentionKernel, Token, TokenRoutingKernel,
};
/// Default workgroup size for compute shaders

View file

@ -3,8 +3,8 @@
//! This module handles shader compilation, pipeline creation, and bind group
//! management for GPU compute operations.
use std::sync::Arc;
use dashmap::DashMap;
use std::sync::Arc;
use tracing::{debug, info};
use wgpu::{Device, ShaderModule};
@ -332,10 +332,12 @@ impl PipelineCache {
info!("Creating and caching pipeline: {}", name);
let pipeline = ComputePipeline::from_shader(&self.device, shader_source, entry_point, bindings)?;
let pipeline =
ComputePipeline::from_shader(&self.device, shader_source, entry_point, bindings)?;
let pipeline = Arc::new(pipeline);
self.pipelines.insert(name.to_string(), Arc::clone(&pipeline));
self.pipelines
.insert(name.to_string(), Arc::clone(&pipeline));
Ok(pipeline)
}

View file

@ -89,11 +89,7 @@ impl HyperbolicAdapter {
let norm_x_sq: f32 = x.iter().map(|v| v * v).sum();
let norm_y_sq: f32 = y.iter().map(|v| v * v).sum();
let diff_sq: f32 = x
.iter()
.zip(y.iter())
.map(|(a, b)| (a - b) * (a - b))
.sum();
let diff_sq: f32 = x.iter().zip(y.iter()).map(|(a, b)| (a - b) * (a - b)).sum();
let denom = (1.0 - norm_x_sq).max(EPS) * (1.0 - norm_y_sq).max(EPS);
let inner = 1.0 + 2.0 * diff_sq / denom;

View file

@ -178,26 +178,11 @@ mod tests {
fn test_hierarchy_levels() {
let computer = DepthComputer::new(-1.0);
assert_eq!(
computer.classify_level(0.3),
HierarchyLevel::Root
);
assert_eq!(
computer.classify_level(0.7),
HierarchyLevel::High
);
assert_eq!(
computer.classify_level(1.5),
HierarchyLevel::Mid
);
assert_eq!(
computer.classify_level(2.5),
HierarchyLevel::Deep
);
assert_eq!(
computer.classify_level(4.0),
HierarchyLevel::VeryDeep
);
assert_eq!(computer.classify_level(0.3), HierarchyLevel::Root);
assert_eq!(computer.classify_level(0.7), HierarchyLevel::High);
assert_eq!(computer.classify_level(1.5), HierarchyLevel::Mid);
assert_eq!(computer.classify_level(2.5), HierarchyLevel::Deep);
assert_eq!(computer.classify_level(4.0), HierarchyLevel::VeryDeep);
}
#[test]

View file

@ -176,8 +176,7 @@ impl HyperbolicEnergy {
for edge in &self.edge_energies {
let avg_depth = edge.avg_depth();
let bucket_idx =
((avg_depth - self.min_depth) / bucket_size).floor() as usize;
let bucket_idx = ((avg_depth - self.min_depth) / bucket_size).floor() as usize;
let bucket_idx = bucket_idx.min(num_buckets - 1);
buckets[bucket_idx].total_energy += edge.weighted_energy;

View file

@ -323,7 +323,9 @@ mod tests {
coherence.insert_node(2, vec![0.5, 0.5, 0.5, 0.5]).unwrap();
let residual = vec![0.1, 0.1, 0.1, 0.1];
let weighted = coherence.weighted_edge_energy(1, 2, &residual, 1.0).unwrap();
let weighted = coherence
.weighted_edge_energy(1, 2, &residual, 1.0)
.unwrap();
assert!(weighted.weighted_energy > 0.0);
assert!(weighted.depth_weight > 1.0); // Should have depth scaling
@ -338,14 +340,19 @@ mod tests {
};
let mut coherence = HyperbolicCoherence::new(config);
coherence.insert_node(1, vec![0.05, 0.05, 0.05, 0.05]).unwrap();
coherence
.insert_node(1, vec![0.05, 0.05, 0.05, 0.05])
.unwrap();
coherence.insert_node(2, vec![0.7, 0.7, 0.0, 0.0]).unwrap();
let level1 = coherence.hierarchy_level(1).unwrap();
let level2 = coherence.hierarchy_level(2).unwrap();
// Node 1 should be at higher level (closer to root)
assert!(matches!(level1, HierarchyLevel::Root | HierarchyLevel::High));
assert!(matches!(
level1,
HierarchyLevel::Root | HierarchyLevel::High
));
// Node 2 should be deeper
assert!(matches!(
level2,

View file

@ -130,7 +130,13 @@ impl Activation {
pub fn apply(&self, x: f32) -> f32 {
match self {
Self::ReLU => x.max(0.0),
Self::LeakyReLU => if x > 0.0 { x } else { 0.01 * x },
Self::LeakyReLU => {
if x > 0.0 {
x
} else {
0.01 * x
}
}
Self::GELU => {
// Approximation: 0.5 * x * (1 + tanh(sqrt(2/pi) * (x + 0.044715 * x^3)))
0.5 * x * (1.0 + ((0.7978845608 * (x + 0.044715 * x.powi(3))).tanh()))
@ -144,12 +150,25 @@ impl Activation {
/// Apply the derivative of the activation function.
pub fn derivative(&self, x: f32) -> f32 {
match self {
Self::ReLU => if x > 0.0 { 1.0 } else { 0.0 },
Self::LeakyReLU => if x > 0.0 { 1.0 } else { 0.01 },
Self::ReLU => {
if x > 0.0 {
1.0
} else {
0.0
}
}
Self::LeakyReLU => {
if x > 0.0 {
1.0
} else {
0.01
}
}
Self::GELU => {
// Approximation of GELU derivative
let t = (0.7978845608 * (x + 0.044715 * x.powi(3))).tanh();
0.5 * (1.0 + t) + 0.5 * x * (1.0 - t * t) * 0.7978845608 * (1.0 + 3.0 * 0.044715 * x * x)
0.5 * (1.0 + t)
+ 0.5 * x * (1.0 - t * t) * 0.7978845608 * (1.0 + 3.0 * 0.044715 * x * x)
}
Self::Tanh => 1.0 - x.tanh().powi(2),
Self::Sigmoid => {
@ -303,7 +322,9 @@ impl SchedulerConfig {
SchedulerType::CosineAnnealing { t_max, eta_min } => {
let t = (step % t_max) as f32;
let t_max = *t_max as f32;
*eta_min + (self.initial_lr - eta_min) * (1.0 + (std::f32::consts::PI * t / t_max).cos()) / 2.0
*eta_min
+ (self.initial_lr - eta_min) * (1.0 + (std::f32::consts::PI * t / t_max).cos())
/ 2.0
}
}
}

View file

@ -21,11 +21,11 @@ pub enum MapState {
/// A simple dense layer.
#[derive(Debug, Clone)]
struct DenseLayer {
weights: Vec<Vec<f32>>, // [output_dim][input_dim]
biases: Vec<f32>, // [output_dim]
weights: Vec<Vec<f32>>, // [output_dim][input_dim]
biases: Vec<f32>, // [output_dim]
weight_gradients: Vec<Vec<f32>>,
bias_gradients: Vec<f32>,
input_cache: Vec<f32>, // For backprop
input_cache: Vec<f32>, // For backprop
pre_activation_cache: Vec<f32>,
activation: Activation,
}
@ -98,7 +98,11 @@ impl DenseLayer {
}
fn apply_gradients(&mut self, lr: f32, weight_decay: f32) {
for (weights_row, grads_row) in self.weights.iter_mut().zip(self.weight_gradients.iter_mut()) {
for (weights_row, grads_row) in self
.weights
.iter_mut()
.zip(self.weight_gradients.iter_mut())
{
for (w, g) in weights_row.iter_mut().zip(grads_row.iter_mut()) {
*w -= lr * (*g + weight_decay * *w);
*g = 0.0; // Reset gradient
@ -154,7 +158,9 @@ impl EwcState {
}
let mut loss = 0.0;
for ((f, opt), curr) in self.fisher.iter()
for ((f, opt), curr) in self
.fisher
.iter()
.zip(self.optimal_weights.iter())
.zip(current_weights.iter())
{
@ -189,7 +195,9 @@ pub struct LearnedRestrictionMap {
impl LearnedRestrictionMap {
/// Create a new learned restriction map.
pub fn new(config: RestrictionMapConfig) -> LearnedRhoResult<Self> {
config.validate().map_err(LearnedRhoError::InvalidConfiguration)?;
config
.validate()
.map_err(LearnedRhoError::InvalidConfiguration)?;
let mut layers = Vec::with_capacity(config.num_layers + 1);
@ -217,9 +225,10 @@ impl LearnedRestrictionMap {
));
// Count total parameters for EWC
let num_params: usize = layers.iter().map(|l| {
l.weights.iter().map(|r| r.len()).sum::<usize>() + l.biases.len()
}).sum();
let num_params: usize = layers
.iter()
.map(|l| l.weights.iter().map(|r| r.len()).sum::<usize>() + l.biases.len())
.sum();
let replay = ReplayBuffer::new(config.replay_capacity);
let ewc = EwcState::new(num_params, config.ewc_lambda);
@ -258,7 +267,10 @@ impl LearnedRestrictionMap {
/// Apply the learned restriction map (forward pass).
pub fn apply(&mut self, input: &[f32]) -> LearnedRhoResult<Vec<f32>> {
if input.len() != self.config.input_dim {
return Err(LearnedRhoError::dim_mismatch(self.config.input_dim, input.len()));
return Err(LearnedRhoError::dim_mismatch(
self.config.input_dim,
input.len(),
));
}
let mut x = input.to_vec();
@ -278,10 +290,16 @@ impl LearnedRestrictionMap {
expected_residual: &[f32],
) -> LearnedRhoResult<TrainingMetrics> {
if source.len() != self.config.input_dim {
return Err(LearnedRhoError::dim_mismatch(self.config.input_dim, source.len()));
return Err(LearnedRhoError::dim_mismatch(
self.config.input_dim,
source.len(),
));
}
if expected_residual.len() != self.config.output_dim {
return Err(LearnedRhoError::dim_mismatch(self.config.output_dim, expected_residual.len()));
return Err(LearnedRhoError::dim_mismatch(
self.config.output_dim,
expected_residual.len(),
));
}
self.state = MapState::Training;
@ -307,7 +325,12 @@ impl LearnedRestrictionMap {
}
// Compute gradient norm
let gradient_norm: f32 = self.layers.iter().map(|l| l.gradient_norm()).sum::<f32>().sqrt();
let gradient_norm: f32 = self
.layers
.iter()
.map(|l| l.gradient_norm())
.sum::<f32>()
.sqrt();
// Get current learning rate
let lr = self.config.scheduler.get_lr(self.training_step);
@ -415,7 +438,11 @@ impl LearnedRestrictionMap {
let duration_ms = start.elapsed().as_millis() as u64;
Ok(TrainingResult::from_metrics(&metrics_list, epoch, duration_ms))
Ok(TrainingResult::from_metrics(
&metrics_list,
epoch,
duration_ms,
))
}
/// Get map statistics.
@ -526,11 +553,7 @@ mod tests {
// Add some experiences
for _ in 0..20 {
map.add_experience(
vec![1.0; 32],
vec![2.0; 32],
vec![0.1; 16],
);
map.add_experience(vec![1.0; 32], vec![2.0; 32], vec![0.1; 16]);
}
let metrics = map.train_from_replay().unwrap();

View file

@ -46,7 +46,7 @@ mod error;
mod map;
mod training;
pub use config::{RestrictionMapConfig, OptimizerConfig, SchedulerConfig};
pub use config::{OptimizerConfig, RestrictionMapConfig, SchedulerConfig};
pub use error::{LearnedRhoError, LearnedRhoResult};
pub use map::{LearnedRestrictionMap, MapState};
pub use training::{TrainingBatch, TrainingMetrics, TrainingResult};

View file

@ -110,7 +110,10 @@ impl ReplayBuffer {
for i in 0..batch_size.min(n) {
// Simple LCG for pseudo-random selection
let idx = ((seed.wrapping_mul(6364136223846793005).wrapping_add(i as u64)) % n as u64) as usize;
let idx = ((seed
.wrapping_mul(6364136223846793005)
.wrapping_add(i as u64))
% n as u64) as usize;
let exp = &self.experiences[idx];
batch.add(
exp.source.clone(),
@ -249,11 +252,7 @@ mod tests {
let mut buffer = ReplayBuffer::new(100);
for i in 0..50 {
buffer.add(
vec![i as f32],
vec![i as f32 + 1.0],
vec![0.1],
);
buffer.add(vec![i as f32], vec![i as f32 + 1.0], vec![0.1]);
}
assert_eq!(buffer.len(), 50);

View file

@ -258,129 +258,192 @@ pub mod types;
// Re-export core types for convenience
pub use types::{
ActorId,
ApproverId,
EdgeId,
GraphId,
Hash,
LineageId,
NamespaceId,
// Identifiers
NodeId, EdgeId, GraphId, ScopeId, NamespaceId,
PolicyBundleId, WitnessId, LineageId, ActorId, ApproverId,
NodeId,
PolicyBundleId,
ScopeId,
// Primitives
Timestamp, Hash, Version,
Timestamp,
Version,
WitnessId,
};
pub use error::{
CoherenceError, SubstrateError, GovernanceError, ExecutionError, StorageError,
};
pub use error::{CoherenceError, ExecutionError, GovernanceError, StorageError, SubstrateError};
// Re-export security types
pub use security::{
GraphLimits, ResourceLimits, SecurityConfig,
InputValidator, PathValidator, StateValidator, ValidationError, ValidationResult,
GraphLimits, InputValidator, PathValidator, ResourceLimits, SecurityConfig, StateValidator,
ValidationError, ValidationResult,
};
pub use events::DomainEvent;
// Re-export substrate types
pub use substrate::{
SheafGraph, SheafNode, SheafEdge, RestrictionMap,
SheafSubgraph, NodeMetadata,
NodeMetadata, RestrictionMap, SheafEdge, SheafGraph, SheafNode, SheafSubgraph,
};
// Re-export coherence types
pub use coherence::{
CoherenceEngine, CoherenceEnergy, CoherenceConfig,
ResidualCache, EnergyHistory,
CoherenceConfig, CoherenceEnergy, CoherenceEngine, EnergyHistory, ResidualCache,
};
// Re-export cohomology types
pub use cohomology::{
// Simplex and simplicial complex
Simplex, SimplexId, SimplicialComplex, Chain, Cochain,
// Sheaf types
Sheaf, Stalk, SheafSection, LocalSection, SheafBuilder,
Activation,
BettiNumbers,
Chain,
Coboundary,
Cochain,
// Cocycle and coboundary
Cocycle, CocycleBuilder, Coboundary,
Cocycle,
CocycleBuilder,
CohomologyComputer,
CohomologyConfig,
// Cohomology groups
CohomologyGroup, CohomologyComputer, CohomologyConfig, BettiNumbers,
// Laplacian
SheafLaplacian, LaplacianConfig, LaplacianSpectrum, HarmonicRepresentative,
CohomologyGroup,
CohomologyPooling,
DiffusionResult,
HarmonicRepresentative,
LaplacianConfig,
LaplacianSpectrum,
LocalSection,
Obstruction,
// Obstruction detection
ObstructionDetector, Obstruction, ObstructionSeverity, ObstructionReport,
ObstructionDetector,
ObstructionIndicator,
ObstructionReport,
ObstructionSeverity,
PoolingMethod,
// Sheaf types
Sheaf,
SheafBuilder,
SheafConvolution,
// Diffusion
SheafDiffusion, SheafDiffusionConfig, DiffusionResult, ObstructionIndicator,
SheafDiffusion,
SheafDiffusionConfig,
// Laplacian
SheafLaplacian,
SheafNeuralConfig,
// Neural network layers
SheafNeuralLayer, SheafNeuralConfig, SheafConvolution, CohomologyPooling,
PoolingMethod, Activation,
SheafNeuralLayer,
SheafSection,
// Simplex and simplicial complex
Simplex,
SimplexId,
SimplicialComplex,
Stalk,
};
// Re-export governance types
pub use governance::{
// Policy types
PolicyBundle, PolicyBundleBuilder, PolicyBundleRef, PolicyBundleStatus,
ThresholdConfig, EscalationRule, ApprovalSignature, ApproverId as GovApproverId,
PolicyError,
// Witness types (governance's own witness format)
WitnessRecord as GovWitnessRecord, WitnessId as GovWitnessId,
WitnessChainError, WitnessError,
// Lineage types
LineageRecord, LineageId as GovLineageId, Operation, EntityRef, LineageError,
// Repository traits
PolicyRepository, WitnessRepository, LineageRepository,
// Common types
Hash as GovHash, Timestamp as GovTimestamp, Version as GovVersion,
ApprovalSignature,
ApproverId as GovApproverId,
EntityRef,
EscalationRule,
// Top-level error
GovernanceError as GovError,
// Common types
Hash as GovHash,
LineageError,
LineageId as GovLineageId,
// Lineage types
LineageRecord,
LineageRepository,
Operation,
// Policy types
PolicyBundle,
PolicyBundleBuilder,
PolicyBundleRef,
PolicyBundleStatus,
PolicyError,
// Repository traits
PolicyRepository,
ThresholdConfig,
Timestamp as GovTimestamp,
Version as GovVersion,
WitnessChainError,
WitnessError,
WitnessId as GovWitnessId,
// Witness types (governance's own witness format)
WitnessRecord as GovWitnessRecord,
WitnessRepository,
};
// Re-export execution types (coherence gate and compute ladder)
pub use execution::{
// Gate and ladder
CoherenceGate, GateDecision, ComputeLane, EnergySnapshot,
LaneThresholds, EscalationReason,
// Actions
Action, ActionExecutor, ActionId, ActionImpact, ActionMetadata, ActionResult,
ExecutionContext, ExecutionResult, ExecutorConfig, ExecutorStats,
// Witness (execution's witness format - aliased to avoid conflict with types::WitnessId)
WitnessRecord as ExecWitnessRecord, WitnessId as ExecWitnessId,
Action,
ActionExecutor,
ActionId,
ActionImpact,
ActionMetadata,
ActionResult,
// Gate and ladder
CoherenceGate,
ComputeLane,
EnergySnapshot,
EscalationReason,
ExecutionContext,
ExecutionResult,
ExecutorConfig,
ExecutorStats,
GateDecision,
LaneThresholds,
PolicyBundleRef as ExecutionPolicyRef,
// Scope
ScopeId as ExecutionScopeId,
WitnessId as ExecWitnessId,
// Witness (execution's witness format - aliased to avoid conflict with types::WitnessId)
WitnessRecord as ExecWitnessRecord,
};
// Conditional re-exports based on features
#[cfg(feature = "tiles")]
pub use tiles::{CoherenceFabric, FabricReport, TileAdapter, ShardMap};
pub use tiles::{CoherenceFabric, FabricReport, ShardMap, TileAdapter};
#[cfg(feature = "sona")]
pub use sona_tuning::{SonaThresholdTuner, ThresholdAdjustment, ThresholdConfig as SonaThresholdConfig};
pub use sona_tuning::{
SonaThresholdTuner, ThresholdAdjustment, ThresholdConfig as SonaThresholdConfig,
};
#[cfg(feature = "neural-gate")]
pub use neural_gate::{NeuralCoherenceGate, NeuralDecision, WitnessEncoding};
#[cfg(feature = "learned-rho")]
pub use learned_rho::{LearnedRestrictionMap, TrainingBatch, RestrictionMapConfig};
pub use learned_rho::{LearnedRestrictionMap, RestrictionMapConfig, TrainingBatch};
#[cfg(feature = "hyperbolic")]
pub use hyperbolic::{
HyperbolicCoherence, HyperbolicCoherenceConfig, HyperbolicAdapter,
DepthComputer, HierarchyLevel, HyperbolicEnergy, WeightedResidual,
DepthComputer, HierarchyLevel, HyperbolicAdapter, HyperbolicCoherence,
HyperbolicCoherenceConfig, HyperbolicEnergy, WeightedResidual,
};
#[cfg(feature = "mincut")]
pub use mincut::{
IncoherenceIsolator, MinCutAdapter, MinCutConfig,
IsolationRegion, IsolationResult, IsolationMetrics,
IncoherenceIsolator, IsolationMetrics, IsolationRegion, IsolationResult, MinCutAdapter,
MinCutConfig,
};
#[cfg(feature = "attention")]
pub use attention::{
AttentionCoherence, AttentionCoherenceConfig, AttentionAdapter,
TopologyGate, TopologyGateResult, MoEResidualProcessor, ExpertRouting,
DiffusionSmoothing, SmoothedEnergy, WeightedEdgeResidual, AttentionEnergyAnalysis,
AttentionAdapter, AttentionCoherence, AttentionCoherenceConfig, AttentionEnergyAnalysis,
DiffusionSmoothing, ExpertRouting, MoEResidualProcessor, SmoothedEnergy, TopologyGate,
TopologyGateResult, WeightedEdgeResidual,
};
#[cfg(feature = "distributed")]
pub use distributed::{
DistributedCoherence, DistributedCoherenceConfig, RaftAdapter,
CoherenceStateMachine, ClusterStatus, CoherenceStatus, NodeRole,
ClusterStatus, CoherenceStateMachine, CoherenceStatus, DistributedCoherence,
DistributedCoherenceConfig, NodeRole, RaftAdapter,
};
#[cfg(feature = "ruvllm")]
@ -390,28 +453,46 @@ pub use ruvllm_integration::{
#[cfg(feature = "gpu")]
pub use gpu::{
// Device management
GpuDevice, GpuDeviceInfo, GpuDeviceOptions,
// Buffer management
GpuBuffer, GpuBufferManager, GpuBufferPool, BufferUsage, BufferUsageFlags, BufferKey,
BindingDesc,
BindingType,
BufferKey,
BufferUsage,
BufferUsageFlags,
ComputeEnergyKernel,
// Pipeline management
ComputePipeline, PipelineCache, BindingDesc, BindingType,
// Dispatch and synchronization
GpuDispatcher, DispatchConfig, DispatchBuilder,
// GPU coherence engine
GpuCoherenceEngine, GpuConfig, GpuCapabilities, GpuCoherenceEnergy,
ComputePipeline,
// Kernel types
ComputeResidualsKernel, ComputeEnergyKernel, SheafAttentionKernel, TokenRoutingKernel,
ComputeResidualsKernel,
DispatchBuilder,
DispatchConfig,
// Buffer management
GpuBuffer,
GpuBufferManager,
GpuBufferPool,
GpuCapabilities,
GpuCoherenceEnergy,
// GPU coherence engine
GpuCoherenceEngine,
GpuConfig,
// Device management
GpuDevice,
GpuDeviceInfo,
GpuDeviceOptions,
// Dispatch and synchronization
GpuDispatcher,
// Errors
GpuError, GpuResult,
GpuError,
GpuResult,
PipelineCache,
SheafAttentionKernel,
TokenRoutingKernel,
};
#[cfg(feature = "simd")]
pub use simd::{
SimdWidth, SimdContext, best_simd_width,
dot_product_simd, norm_squared_simd, subtract_simd, scale_simd,
matmul_simd, matvec_simd,
batch_residuals_simd, weighted_energy_sum_simd, batch_lane_assignment_simd,
batch_lane_assignment_simd, batch_residuals_simd, best_simd_width, dot_product_simd,
matmul_simd, matvec_simd, norm_squared_simd, scale_simd, subtract_simd,
weighted_energy_sum_simd, SimdContext, SimdWidth,
};
// ============================================================================
@ -421,35 +502,52 @@ pub use simd::{
/// Convenient imports for common use cases
pub mod prelude {
pub use crate::{
// Core types
NodeId, EdgeId, GraphId, ScopeId,
Timestamp, Hash, Version,
// Substrate
SheafGraph, SheafNode, SheafEdge, RestrictionMap,
CoherenceEnergy,
// Coherence
CoherenceEngine, CoherenceEnergy,
// Cohomology
SheafLaplacian, SheafDiffusion, ObstructionDetector,
CohomologyGroup, CohomologyComputer, SheafNeuralLayer,
// Governance
PolicyBundle, ThresholdConfig,
GovWitnessRecord as WitnessRecord, // Re-export governance witness as default
// Execution
CoherenceGate, GateDecision, ComputeLane,
// Security
InputValidator, SecurityConfig,
CoherenceEngine,
// Errors
CoherenceError, ValidationError,
CoherenceError,
// Execution
CoherenceGate,
CohomologyComputer,
CohomologyGroup,
ComputeLane,
// Events
DomainEvent,
EdgeId,
GateDecision,
GovWitnessRecord as WitnessRecord, // Re-export governance witness as default
GraphId,
Hash,
// Security
InputValidator,
// Core types
NodeId,
ObstructionDetector,
// Governance
PolicyBundle,
RestrictionMap,
ScopeId,
SecurityConfig,
SheafDiffusion,
SheafEdge,
// Substrate
SheafGraph,
// Cohomology
SheafLaplacian,
SheafNeuralLayer,
SheafNode,
ThresholdConfig,
Timestamp,
ValidationError,
Version,
};
}

View file

@ -154,10 +154,7 @@ impl MinCutAdapter {
}
/// Compute isolation for high-energy vertices
pub fn compute_isolation(
&self,
high_energy_vertices: &HashSet<VertexId>,
) -> Result<CutResult> {
pub fn compute_isolation(&self, high_energy_vertices: &HashSet<VertexId>) -> Result<CutResult> {
if high_energy_vertices.is_empty() {
return Ok(CutResult {
isolated_set: HashSet::new(),

View file

@ -210,8 +210,8 @@ impl IsolationComparison {
.copied()
.collect();
let union_size = first.isolated_vertices.len() + second.isolated_vertices.len()
- common.len();
let union_size =
first.isolated_vertices.len() + second.isolated_vertices.len() - common.len();
let jaccard = if union_size > 0 {
common.len() as f64 / union_size as f64
} else {

View file

@ -196,7 +196,11 @@ impl std::fmt::Display for MetricsSummary {
writeln!(f, " Avg query time: {:.2} us", self.avg_query_time_us)?;
writeln!(f, " Max isolation size: {}", self.max_isolation_size)?;
writeln!(f, " Updates per build: {:.2}", self.updates_per_build)?;
writeln!(f, " Isolation efficiency: {:.4}", self.isolation_efficiency)
writeln!(
f,
" Isolation efficiency: {:.4}",
self.isolation_efficiency
)
}
}

View file

@ -75,10 +75,9 @@ impl DecisionConfidence {
supporting_evidence: usize,
) -> Self {
// Combine confidences with weighted average
let overall = (energy_confidence * 0.4
+ dendritic_confidence * 0.3
+ oscillator_confidence * 0.3)
.clamp(0.0, 1.0);
let overall =
(energy_confidence * 0.4 + dendritic_confidence * 0.3 + oscillator_confidence * 0.3)
.clamp(0.0, 1.0);
Self {
overall,

View file

@ -70,7 +70,9 @@ impl Hypervector {
for i in 0..dim {
// Simple LCG for deterministic generation
let mixed = seed.wrapping_mul(6364136223846793005).wrapping_add(i as u64);
let mixed = seed
.wrapping_mul(6364136223846793005)
.wrapping_add(i as u64);
let normalized = (mixed as f32 / u64::MAX as f32) * 2.0 - 1.0;
components.push(normalized);
}
@ -358,13 +360,7 @@ mod tests {
#[test]
fn test_witness_encoding() {
let enc = WitnessEncoding::new(
"test_witness",
0.5,
true,
&[1, 2, 3, 4],
1000,
);
let enc = WitnessEncoding::new("test_witness", 0.5, true, &[1, 2, 3, 4], 1000);
assert_eq!(enc.witness_id, "test_witness");
assert!(enc.allow);

View file

@ -52,7 +52,8 @@ impl HysteresisTracker {
fn update(&mut self, energy: f32) -> Option<HysteresisState> {
// Apply exponential smoothing
self.smoothed_energy = self.smoothing * self.smoothed_energy + (1.0 - self.smoothing) * energy;
self.smoothed_energy =
self.smoothing * self.smoothed_energy + (1.0 - self.smoothing) * energy;
let now = current_time_ms();
let dwell_time = now - self.state_entered_ms;
@ -260,7 +261,8 @@ impl NeuralCoherenceGate {
/// Create a new neural coherence gate.
pub fn new(config: NeuralGateConfig) -> Self {
let hysteresis = HysteresisTracker::new(&config.hysteresis);
let dendrite = DendriticDetector::new(config.coincidence_window_us, config.num_branches / 2);
let dendrite =
DendriticDetector::new(config.coincidence_window_us, config.num_branches / 2);
let workspace = GlobalWorkspace::new(&config.workspace);
let hdc_memory = HdcMemory::new(config.hdc_dimension, config.memory_capacity);

View file

@ -49,8 +49,8 @@ mod encoding;
mod error;
mod gate;
pub use config::{NeuralGateConfig, HysteresisConfig, WorkspaceConfig, OscillatorConfig};
pub use decision::{NeuralDecision, DecisionConfidence, DecisionTrigger};
pub use encoding::{WitnessEncoding, HypervectorOps};
pub use config::{HysteresisConfig, NeuralGateConfig, OscillatorConfig, WorkspaceConfig};
pub use decision::{DecisionConfidence, DecisionTrigger, NeuralDecision};
pub use encoding::{HypervectorOps, WitnessEncoding};
pub use error::{NeuralGateError, NeuralGateResult};
pub use gate::{NeuralCoherenceGate, GateState};
pub use gate::{GateState, NeuralCoherenceGate};

View file

@ -170,21 +170,27 @@ impl RuvLlmAdapter {
pub fn record_pass(&self, time_us: u64) {
self.stats.requests.fetch_add(1, Ordering::Relaxed);
self.stats.passed.fetch_add(1, Ordering::Relaxed);
self.stats.total_time_us.fetch_add(time_us, Ordering::Relaxed);
self.stats
.total_time_us
.fetch_add(time_us, Ordering::Relaxed);
}
/// Record a failed coherence check.
pub fn record_fail(&self, time_us: u64) {
self.stats.requests.fetch_add(1, Ordering::Relaxed);
self.stats.failed.fetch_add(1, Ordering::Relaxed);
self.stats.total_time_us.fetch_add(time_us, Ordering::Relaxed);
self.stats
.total_time_us
.fetch_add(time_us, Ordering::Relaxed);
}
/// Record an escalation.
pub fn record_escalation(&self, time_us: u64) {
self.stats.requests.fetch_add(1, Ordering::Relaxed);
self.stats.escalated.fetch_add(1, Ordering::Relaxed);
self.stats.total_time_us.fetch_add(time_us, Ordering::Relaxed);
self.stats
.total_time_us
.fetch_add(time_us, Ordering::Relaxed);
}
/// Record a cache hit.

View file

@ -663,7 +663,10 @@ impl SheafCoherenceValidator {
/// 3. Computes coherence energy
/// 4. Evaluates against the gate
/// 5. Returns a ValidationResult with witness
pub fn validate(&mut self, context: &ValidationContext) -> Result<ValidationResult, ValidationError> {
pub fn validate(
&mut self,
context: &ValidationContext,
) -> Result<ValidationResult, ValidationError> {
// Validate the input
context.validate()?;
@ -695,7 +698,10 @@ impl SheafCoherenceValidator {
} else {
WitnessDecision::deny(
decision.lane.as_u8(),
decision.reason.clone().unwrap_or_else(|| "Energy too high".to_string()),
decision
.reason
.clone()
.unwrap_or_else(|| "Energy too high".to_string()),
confidence,
)
};
@ -717,7 +723,9 @@ impl SheafCoherenceValidator {
} else {
ValidationResult::deny(
energy.total_energy,
decision.reason.unwrap_or_else(|| "Coherence threshold exceeded".to_string()),
decision
.reason
.unwrap_or_else(|| "Coherence threshold exceeded".to_string()),
witness,
context.request_id,
)
@ -878,7 +886,10 @@ impl PolicyBundleRef {
fn into_execution_ref(self) -> crate::execution::PolicyBundleRef {
crate::execution::PolicyBundleRef {
id: self.id.0,
version: format!("{}.{}.{}", self.version.major, self.version.minor, self.version.patch),
version: format!(
"{}.{}.{}",
self.version.major, self.version.minor, self.version.patch
),
content_hash: *self.content_hash.as_bytes(),
}
}
@ -915,7 +926,10 @@ mod tests {
.with_response_embedding(vec![1.0, 2.0]);
let result = ctx.validate();
assert!(matches!(result, Err(ValidationError::DimensionMismatch { .. })));
assert!(matches!(
result,
Err(ValidationError::DimensionMismatch { .. })
));
}
#[test]
@ -933,12 +947,7 @@ mod tests {
.with_context_embedding(vec![1.0, 2.0, 3.0])
.with_response_embedding(vec![1.0, 2.0, 3.0]);
let witness = ValidationWitness::new(
&ctx,
0.5,
WitnessDecision::allow(0, 0.9),
None,
);
let witness = ValidationWitness::new(&ctx, 0.5, WitnessDecision::allow(0, 0.9), None);
assert!(witness.verify_integrity());
}
@ -959,11 +968,10 @@ mod tests {
#[test]
fn test_validator_incoherent_response() {
let mut validator = SheafCoherenceValidator::with_defaults()
.with_config(ValidatorConfig {
reflex_threshold: 0.01, // Very strict
..Default::default()
});
let mut validator = SheafCoherenceValidator::with_defaults().with_config(ValidatorConfig {
reflex_threshold: 0.01, // Very strict
..Default::default()
});
// Very different embeddings should be incoherent
let ctx = ValidationContext::new()
@ -997,12 +1005,7 @@ mod tests {
.with_context_embedding(vec![1.0, 2.0, 3.0])
.with_response_embedding(vec![1.0, 2.0, 3.0]);
let witness = ValidationWitness::new(
&ctx,
0.1,
WitnessDecision::allow(0, 0.95),
None,
);
let witness = ValidationWitness::new(&ctx, 0.1, WitnessDecision::allow(0, 0.95), None);
let result = ValidationResult::allow(0.1, witness, ctx.request_id);

View file

@ -554,11 +554,17 @@ mod tests {
// Energy much below threshold should give high confidence
let conf = mapper.confidence_from_energy(0.1);
assert!(conf > 0.7, "Low energy should give high confidence, got {conf}");
assert!(
conf > 0.7,
"Low energy should give high confidence, got {conf}"
);
// Zero energy should give ~1.0 confidence
let conf = mapper.confidence_from_energy(0.0);
assert!(conf > 0.9, "Zero energy should give very high confidence, got {conf}");
assert!(
conf > 0.9,
"Zero energy should give very high confidence, got {conf}"
);
}
#[test]
@ -567,11 +573,17 @@ mod tests {
// Energy above threshold should give low confidence
let conf = mapper.confidence_from_energy(3.0);
assert!(conf < 0.3, "High energy should give low confidence, got {conf}");
assert!(
conf < 0.3,
"High energy should give low confidence, got {conf}"
);
// Very high energy should give ~0 confidence
let conf = mapper.confidence_from_energy(10.0);
assert!(conf < 0.01, "Very high energy should give near-zero confidence, got {conf}");
assert!(
conf < 0.01,
"Very high energy should give near-zero confidence, got {conf}"
);
}
#[test]
@ -580,7 +592,10 @@ mod tests {
// Confidence should decrease as energy increases
let energies = [0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 5.0];
let confidences: Vec<f32> = energies.iter().map(|&e| mapper.confidence_from_energy(e)).collect();
let confidences: Vec<f32> = energies
.iter()
.map(|&e| mapper.confidence_from_energy(e))
.collect();
for i in 1..confidences.len() {
assert!(
@ -635,7 +650,10 @@ mod tests {
let score = mapper.compute_confidence(&energy);
assert!(score.value > 0.5, "Low energy should give >0.5 confidence");
assert!(score.witness_backed, "Should be witness-backed with edge data");
assert!(
score.witness_backed,
"Should be witness-backed with edge data"
);
assert_eq!(score.edge_count, 3);
assert!(!score.explanation.is_empty());
}
@ -677,11 +695,26 @@ mod tests {
#[test]
fn test_confidence_score_levels() {
assert_eq!(ConfidenceScore::from_value(0.95).level(), ConfidenceLevel::VeryHigh);
assert_eq!(ConfidenceScore::from_value(0.75).level(), ConfidenceLevel::High);
assert_eq!(ConfidenceScore::from_value(0.55).level(), ConfidenceLevel::Moderate);
assert_eq!(ConfidenceScore::from_value(0.35).level(), ConfidenceLevel::Low);
assert_eq!(ConfidenceScore::from_value(0.15).level(), ConfidenceLevel::VeryLow);
assert_eq!(
ConfidenceScore::from_value(0.95).level(),
ConfidenceLevel::VeryHigh
);
assert_eq!(
ConfidenceScore::from_value(0.75).level(),
ConfidenceLevel::High
);
assert_eq!(
ConfidenceScore::from_value(0.55).level(),
ConfidenceLevel::Moderate
);
assert_eq!(
ConfidenceScore::from_value(0.35).level(),
ConfidenceLevel::Low
);
assert_eq!(
ConfidenceScore::from_value(0.15).level(),
ConfidenceLevel::VeryLow
);
}
#[test]
@ -717,13 +750,25 @@ mod tests {
// Very large energy should not cause overflow
let conf = mapper.confidence_from_energy(1000.0);
assert!(conf >= 0.0 && conf <= 1.0, "Large energy gave invalid confidence: {conf}");
assert!(conf < 0.001, "Large energy should give near-zero confidence");
assert!(
conf >= 0.0 && conf <= 1.0,
"Large energy gave invalid confidence: {conf}"
);
assert!(
conf < 0.001,
"Large energy should give near-zero confidence"
);
// Negative energy (shouldn't happen, but test stability)
let conf = mapper.confidence_from_energy(-100.0);
assert!(conf >= 0.0 && conf <= 1.0, "Negative energy gave invalid confidence: {conf}");
assert!(conf > 0.999, "Negative energy should give near-one confidence");
assert!(
conf >= 0.0 && conf <= 1.0,
"Negative energy gave invalid confidence: {conf}"
);
assert!(
conf > 0.999,
"Negative energy should give near-one confidence"
);
}
#[test]

View file

@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::time::Instant;
use crate::coherence::{CoherenceEngine, CoherenceEnergy};
use crate::coherence::{CoherenceEnergy, CoherenceEngine};
use crate::execution::ComputeLane;
use crate::governance::PolicyBundle;
@ -284,8 +284,18 @@ impl LlmCoherenceGate {
.map(|(a, b)| a * b)
.sum();
let mag_a: f32 = response.context_embedding.iter().map(|x| x * x).sum::<f32>().sqrt();
let mag_b: f32 = response.response_embedding.iter().map(|x| x * x).sum::<f32>().sqrt();
let mag_a: f32 = response
.context_embedding
.iter()
.map(|x| x * x)
.sum::<f32>()
.sqrt();
let mag_b: f32 = response
.response_embedding
.iter()
.map(|x| x * x)
.sum::<f32>()
.sqrt();
if mag_a == 0.0 || mag_b == 0.0 {
return 1.0;
@ -309,14 +319,18 @@ impl LlmCoherenceGate {
/// Estimate hallucination probability.
fn estimate_hallucination_prob(&self, analysis: &CoherenceAnalysis) -> f64 {
// Combine scores to estimate hallucination probability
let combined = (analysis.semantic_score + analysis.factual_score + analysis.citation_score) / 3.0;
let combined =
(analysis.semantic_score + analysis.factual_score + analysis.citation_score) / 3.0;
// Higher combined score = lower hallucination probability
(1.0 - combined) * self.config.hallucination_sensitivity
}
/// Determine the gate decision based on analysis.
fn determine_decision(&self, analysis: &CoherenceAnalysis) -> (bool, ComputeLane, LlmGateReason) {
fn determine_decision(
&self,
analysis: &CoherenceAnalysis,
) -> (bool, ComputeLane, LlmGateReason) {
// Check for hallucination
if analysis.hallucination_prob > self.config.hallucination_sensitivity {
return (

View file

@ -65,9 +65,9 @@
//!
//! - ADR-CE-019: Memory as Nodes
use crate::substrate::edge::{EdgeId, SheafEdge, SheafEdgeBuilder};
use crate::substrate::graph::SheafGraph;
use crate::substrate::node::{NodeId, NodeMetadata, SheafNode, SheafNodeBuilder, StateVector};
use crate::substrate::edge::{EdgeId, SheafEdge, SheafEdgeBuilder};
use crate::substrate::restriction::RestrictionMap;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
@ -267,7 +267,11 @@ impl MemoryEntry {
}
/// Add metadata to the entry
pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<serde_json::Value>) -> Self {
pub fn with_metadata(
mut self,
key: impl Into<String>,
value: impl Into<serde_json::Value>,
) -> Self {
self.metadata.insert(key.into(), value.into());
self
}
@ -562,16 +566,12 @@ impl MemoryCoherenceLayer {
// Store in appropriate memory storage
match memory_type {
MemoryType::Agentic => {
self.agentic_memories.insert(
entry.key.clone(),
(memory_id, entry.embedding.clone()),
);
self.agentic_memories
.insert(entry.key.clone(), (memory_id, entry.embedding.clone()));
}
MemoryType::Working => {
self.working_memories.insert(
entry.key.clone(),
(memory_id, entry.embedding.clone()),
);
self.working_memories
.insert(entry.key.clone(), (memory_id, entry.embedding.clone()));
}
MemoryType::Episodic => {
self.episodic_memories.push((
@ -616,7 +616,9 @@ impl MemoryCoherenceLayer {
/// Remove a memory entry
pub fn remove_memory(&mut self, id: MemoryId) -> Result<()> {
let node_id = self.memory_to_node.remove(&id)
let node_id = self
.memory_to_node
.remove(&id)
.ok_or(MemoryCoherenceError::MemoryNotFound(id))?;
self.node_to_memory.remove(&node_id);
@ -748,12 +750,9 @@ impl MemoryCoherenceLayer {
// Create edges
for (other_id, _) in candidates {
if let Some(&other_node) = self.memory_to_node.get(&other_id) {
if let Some(edge_id) = self.create_edge(
other_node,
node_id,
MemoryEdgeType::Semantic,
dim,
)? {
if let Some(edge_id) =
self.create_edge(other_node, node_id, MemoryEdgeType::Semantic, dim)?
{
edges.push(edge_id);
}
}
@ -789,8 +788,8 @@ impl MemoryCoherenceLayer {
let mut edges = Vec::new();
for pattern_node in pattern_nodes {
if let Some(edge_id) = self.create_edge(
pattern_node, // Pattern is source (general)
node_id, // Memory is target (specific)
pattern_node, // Pattern is source (general)
node_id, // Memory is target (specific)
MemoryEdgeType::Hierarchical,
dim,
)? {
@ -893,7 +892,9 @@ impl AgenticMemory for MemoryCoherenceLayer {
}
fn get_pattern(&self, key: &str) -> Option<&[f32]> {
self.agentic_memories.get(key).map(|(_, emb)| emb.as_slice())
self.agentic_memories
.get(key)
.map(|(_, emb)| emb.as_slice())
}
fn pattern_keys(&self) -> Vec<String> {
@ -922,7 +923,9 @@ impl WorkingMemory for MemoryCoherenceLayer {
}
fn get_context(&self, key: &str) -> Option<&[f32]> {
self.working_memories.get(key).map(|(_, emb)| emb.as_slice())
self.working_memories
.get(key)
.map(|(_, emb)| emb.as_slice())
}
fn clear(&mut self) {
@ -954,7 +957,9 @@ impl EpisodicMemory for MemoryCoherenceLayer {
return None;
}
let idx = (sequence - 1) as usize;
self.episodic_memories.get(idx).map(|(_, _, emb)| emb.as_slice())
self.episodic_memories
.get(idx)
.map(|(_, _, emb)| emb.as_slice())
}
fn recent_episodes(&self, n: usize) -> Vec<(u64, &[f32])> {
@ -1131,7 +1136,10 @@ mod tests {
let id = layer.store_pattern("user_preference", &embedding).unwrap();
assert!(layer.has_pattern("user_preference"));
assert_eq!(layer.get_pattern("user_preference"), Some(embedding.as_slice()));
assert_eq!(
layer.get_pattern("user_preference"),
Some(embedding.as_slice())
);
let keys = layer.pattern_keys();
assert_eq!(keys.len(), 1);
@ -1222,8 +1230,13 @@ mod tests {
#[test]
fn test_edge_type_weights() {
assert!(MemoryEdgeType::Temporal.default_weight() > MemoryEdgeType::Semantic.default_weight());
assert!(MemoryEdgeType::Semantic.default_weight() > MemoryEdgeType::Hierarchical.default_weight());
assert!(
MemoryEdgeType::Temporal.default_weight() > MemoryEdgeType::Semantic.default_weight()
);
assert!(
MemoryEdgeType::Semantic.default_weight()
> MemoryEdgeType::Hierarchical.default_weight()
);
}
#[test]
@ -1238,6 +1251,9 @@ mod tests {
let entry = MemoryEntry::new("test", wrong_dim, MemoryType::Agentic);
let result = layer.add_with_coherence(entry);
assert!(matches!(result, Err(MemoryCoherenceError::InvalidDimension { .. })));
assert!(matches!(
result,
Err(MemoryCoherenceError::InvalidDimension { .. })
));
}
}

View file

@ -94,94 +94,118 @@ pub mod adr_references {
// PUBLIC RE-EXPORTS
// ============================================================================
pub use adapter::{
RuvLlmAdapter, AdapterConfig as LlmAdapterConfig, AdapterStats,
};
pub use adapter::{AdapterConfig as LlmAdapterConfig, AdapterStats, RuvLlmAdapter};
pub use bridge::{
PolicyBridge, PolicyBridgeConfig, PolicySyncResult,
SonaBridge, SonaBridgeConfig, LearningFeedback,
LearningFeedback, PolicyBridge, PolicyBridgeConfig, PolicySyncResult, SonaBridge,
SonaBridgeConfig,
};
pub use config::{
LlmCoherenceConfig, GatingMode, ResponsePolicy,
CoherenceThresholds, HallucinationPolicy,
CoherenceThresholds, GatingMode, HallucinationPolicy, LlmCoherenceConfig, ResponsePolicy,
};
pub use error::{
RuvLlmIntegrationError, Result,
};
pub use error::{Result, RuvLlmIntegrationError};
pub use gate::{
LlmCoherenceGate, LlmGateDecision, LlmGateReason,
ResponseCoherence, CoherenceAnalysis,
CoherenceAnalysis, LlmCoherenceGate, LlmGateDecision, LlmGateReason, ResponseCoherence,
};
pub use witness::{
WitnessAdapter, WitnessAdapterConfig, UnifiedWitnessEntry,
WitnessCorrelation, CorrelationId,
CorrelationId, UnifiedWitnessEntry, WitnessAdapter, WitnessAdapterConfig, WitnessCorrelation,
};
pub use witness_log::{
// Core unified witness log types
UnifiedWitnessLog, GenerationWitness, GenerationWitnessId,
CoherenceWitnessSummary,
GenerationWitness,
GenerationWitnessId,
// Witness summaries
InferenceWitnessSummary, CoherenceWitnessSummary,
// Query and statistics
WitnessQuery, UnifiedWitnessStats,
InferenceWitnessSummary,
// Errors
UnifiedWitnessError,
// Core unified witness log types
UnifiedWitnessLog,
UnifiedWitnessStats,
// Query and statistics
WitnessQuery,
};
pub use confidence::{
CoherenceConfidence, ConfidenceLevel, ConfidenceScore, EnergyContributor,
};
pub use confidence::{CoherenceConfidence, ConfidenceLevel, ConfidenceScore, EnergyContributor};
pub use coherence_validator::{
EdgeWeights,
// Core validator
SheafCoherenceValidator, ValidatorConfig,
SheafCoherenceValidator,
// Context and weights
ValidationContext, EdgeWeights,
ValidationContext,
ValidationError,
// Results
ValidationResult, ValidationError,
ValidationResult,
// Witness
ValidationWitness, WitnessDecision,
ValidationWitness,
ValidatorConfig,
WitnessDecision,
};
pub use memory_layer::{
// Core types
MemoryCoherenceLayer, MemoryCoherenceConfig, MemoryCoherenceError,
Result as MemoryResult,
// Memory types
MemoryType, MemoryEdgeType, MemoryEntry, MemoryId, CoherenceResult,
// Traits
AgenticMemory, WorkingMemory, EpisodicMemory,
AgenticMemory,
CoherenceResult,
EpisodicMemory,
MemoryCoherenceConfig,
MemoryCoherenceError,
// Core types
MemoryCoherenceLayer,
MemoryEdgeType,
MemoryEntry,
MemoryId,
// Memory types
MemoryType,
Result as MemoryResult,
WorkingMemory,
};
// Pattern-to-Restriction Bridge (ADR-CE-018)
pub use pattern_bridge::{
// Bridge core
PatternToRestrictionBridge, BridgeConfig, BridgeStats, ExportResult,
BridgeError, BridgeResult,
BridgeConfig,
BridgeError,
BridgeResult,
BridgeStats,
ExportResult,
// Pattern types
PatternData, VerdictData,
PatternData,
// Provider trait
PatternProvider,
// Bridge core
PatternToRestrictionBridge,
VerdictData,
};
// Trait definitions for loose coupling
pub use traits::{
Claim,
ClaimType,
// Coherence validation
CoherenceValidatable, Claim, ClaimType, ContextSource, Fact, SemanticRelation, RelationType,
// Unified witness
UnifiedWitnessProvider, GenerationWitnessRef,
// Pattern bridge trait
PatternBridge, RestrictionMapRef,
// Memory coherence (with aliases to avoid conflicts with memory_layer)
MemoryType as TraitMemoryType, MemoryEntry as TraitMemoryEntry,
MemoryCoherenceProvider, MemoryAddResult,
CoherenceValidatable,
ConfidenceResult as TraitConfidenceResult,
// Confidence
ConfidenceSource, ConfidenceResult as TraitConfidenceResult, UncertaintySource,
ConfidenceSource,
ContextSource,
Fact,
GenerationWitnessRef,
MemoryAddResult,
MemoryCoherenceProvider,
MemoryEntry as TraitMemoryEntry,
// Memory coherence (with aliases to avoid conflicts with memory_layer)
MemoryType as TraitMemoryType,
// Pattern bridge trait
PatternBridge,
RelationType,
RestrictionMapRef,
SemanticRelation,
UncertaintySource,
// Unified witness
UnifiedWitnessProvider,
};
// ============================================================================

View file

@ -61,8 +61,8 @@
//! - ADR-CE-018: Pattern-to-Restriction Bridge
//! - ADR-014: Coherence Engine Architecture
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use thiserror::Error;
// Import learned_rho types when feature is enabled
@ -582,7 +582,10 @@ impl PatternToRestrictionBridge {
/// This registers the learned restriction maps with the graph so they
/// can be used in coherence computations.
#[cfg(feature = "learned-rho")]
pub fn export_to_prime_radiant(&mut self, graph: &mut SheafGraph) -> BridgeResult<ExportResult> {
pub fn export_to_prime_radiant(
&mut self,
graph: &mut SheafGraph,
) -> BridgeResult<ExportResult> {
use crate::substrate::RestrictionMap;
let mut exported_maps = Vec::new();
@ -609,7 +612,10 @@ impl PatternToRestrictionBridge {
/// Export learned maps to a SheafGraph (stub when learned-rho disabled).
#[cfg(not(feature = "learned-rho"))]
pub fn export_to_prime_radiant(&mut self, graph: &mut SheafGraph) -> BridgeResult<ExportResult> {
pub fn export_to_prime_radiant(
&mut self,
graph: &mut SheafGraph,
) -> BridgeResult<ExportResult> {
let exported_categories: Vec<String> = self.restriction_maps.keys().cloned().collect();
self.stats.exports += 1;
@ -638,9 +644,10 @@ impl PatternToRestrictionBridge {
#[cfg(feature = "learned-rho")]
pub fn consolidate(&mut self) -> BridgeResult<()> {
for entry in self.restriction_maps.values_mut() {
entry.map.consolidate().map_err(|e| {
BridgeError::TrainingError(format!("consolidation failed: {}", e))
})?;
entry
.map
.consolidate()
.map_err(|e| BridgeError::TrainingError(format!("consolidation failed: {}", e)))?;
}
Ok(())
}
@ -688,9 +695,8 @@ impl PatternToRestrictionBridge {
..Default::default()
};
let map = LearnedRestrictionMap::new(rho_config).map_err(|e| {
BridgeError::ConfigError(format!("failed to create map: {}", e))
})?;
let map = LearnedRestrictionMap::new(rho_config)
.map_err(|e| BridgeError::ConfigError(format!("failed to create map: {}", e)))?;
self.restriction_maps.insert(
category.to_string(),
@ -754,8 +760,7 @@ impl PatternToRestrictionBridge {
// Update rolling average loss
let n = self.stats.training_steps as f32;
self.stats.avg_loss =
self.stats.avg_loss * ((n - 1.0) / n) + metrics.loss / n;
self.stats.avg_loss = self.stats.avg_loss * ((n - 1.0) / n) + metrics.loss / n;
}
}
@ -910,7 +915,10 @@ mod tests {
impl PatternProvider for MockPatternProvider {
fn get_pattern(&self, pattern_id: &str) -> Option<PatternData> {
self.patterns.iter().find(|p| p.pattern_id == pattern_id).cloned()
self.patterns
.iter()
.find(|p| p.pattern_id == pattern_id)
.cloned()
}
fn get_patterns_by_category(&self, category: &str) -> Vec<PatternData> {

View file

@ -271,7 +271,10 @@ pub struct MemoryEntry {
/// Provider of memory coherence checks.
pub trait MemoryCoherenceProvider {
/// Add a memory entry with coherence checking.
fn add_with_coherence(&mut self, entry: MemoryEntry) -> RuvllmIntegrationResult<MemoryAddResult>;
fn add_with_coherence(
&mut self,
entry: MemoryEntry,
) -> RuvllmIntegrationResult<MemoryAddResult>;
/// Check if adding an entry would cause incoherence.
fn check_coherence(&self, entry: &MemoryEntry) -> RuvllmIntegrationResult<f32>;

View file

@ -352,10 +352,7 @@ impl GenerationWitness {
}
/// Create a genesis witness (first in chain)
pub fn genesis(
inference: InferenceWitnessSummary,
coherence: CoherenceWitnessSummary,
) -> Self {
pub fn genesis(inference: InferenceWitnessSummary, coherence: CoherenceWitnessSummary) -> Self {
Self::new(inference, coherence, None)
}
@ -716,15 +713,9 @@ impl UnifiedWitnessLog {
// Update indices
self.by_id.insert(id, index);
self.by_session
.entry(session_id)
.or_default()
.push(index);
self.by_session.entry(session_id).or_default().push(index);
if let Some(corr_id) = correlation_id {
self.by_correlation
.entry(corr_id)
.or_default()
.push(index);
self.by_correlation.entry(corr_id).or_default().push(index);
}
// Update head

View file

@ -159,11 +159,7 @@ impl InputValidator {
}
/// Validate matrix dimensions
pub fn validate_matrix_dims(
&self,
rows: usize,
cols: usize,
) -> ValidationResult<()> {
pub fn validate_matrix_dims(&self, rows: usize, cols: usize) -> ValidationResult<()> {
let max = self.config.resource_limits.max_matrix_dim;
if rows > max {
@ -267,9 +263,7 @@ impl PathValidator {
// Check for null bytes
if component.contains('\0') {
return Err(ValidationError::InvalidPathChars(
"null byte".to_string(),
));
return Err(ValidationError::InvalidPathChars("null byte".to_string()));
}
Ok(())
@ -290,9 +284,7 @@ impl PathValidator {
for component in path.components() {
match component {
Component::ParentDir => {
return Err(ValidationError::PathTraversal(
path.display().to_string(),
));
return Err(ValidationError::PathTraversal(path.display().to_string()));
}
Component::Normal(s) => {
if let Some(s_str) = s.to_str() {
@ -300,9 +292,7 @@ impl PathValidator {
}
}
Component::Prefix(_) | Component::RootDir => {
return Err(ValidationError::PathTraversal(
path.display().to_string(),
));
return Err(ValidationError::PathTraversal(path.display().to_string()));
}
Component::CurDir => {}
}
@ -311,9 +301,7 @@ impl PathValidator {
// Final check: resolved path should start with base
if let Ok(resolved) = full_path.canonicalize() {
if !resolved.starts_with(&base_canonical) {
return Err(ValidationError::PathTraversal(
path.display().to_string(),
));
return Err(ValidationError::PathTraversal(path.display().to_string()));
}
}
@ -377,7 +365,12 @@ impl StateValidator {
}
/// Validate and clamp state values to a range
pub fn validate_and_clamp(&self, state: &[f32], min: f32, max: f32) -> ValidationResult<Vec<f32>> {
pub fn validate_and_clamp(
&self,
state: &[f32],
min: f32,
max: f32,
) -> ValidationResult<Vec<f32>> {
if state.is_empty() {
return Err(ValidationError::EmptyState);
}
@ -399,7 +392,11 @@ impl StateValidator {
}
// Clamp infinite values to min/max
let clamped = if val.is_infinite() {
if val.is_sign_positive() { max } else { min }
if val.is_sign_positive() {
max
} else {
min
}
} else {
val.clamp(min, max)
};
@ -428,9 +425,8 @@ pub fn is_valid_identifier(s: &str) -> bool {
}
// Rest can be alphanumeric, dash, underscore, or dot
s.chars().all(|c| {
c.is_ascii_alphanumeric() || c == '-' || c == '_' || c == '.'
})
s.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_' || c == '.')
}
/// Check if a state vector is valid (no NaN/Infinity)
@ -463,7 +459,9 @@ pub fn sanitize_path_component(component: &str) -> Option<String> {
/// Validate a dimension value
pub fn validate_dimension(dim: usize, max: usize) -> ValidationResult<()> {
if dim == 0 {
return Err(ValidationError::Custom("Dimension cannot be zero".to_string()));
return Err(ValidationError::Custom(
"Dimension cannot be zero".to_string(),
));
}
if dim > max {
return Err(ValidationError::MatrixDimensionTooLarge { dim, max });
@ -544,10 +542,22 @@ mod tests {
#[test]
fn test_sanitize_path() {
assert_eq!(sanitize_path_component("valid_name"), Some("valid_name".to_string()));
assert_eq!(sanitize_path_component("file.txt"), Some("file.txt".to_string()));
assert_eq!(sanitize_path_component("bad/path"), Some("badpath".to_string()));
assert_eq!(sanitize_path_component("bad\\path"), Some("badpath".to_string()));
assert_eq!(
sanitize_path_component("valid_name"),
Some("valid_name".to_string())
);
assert_eq!(
sanitize_path_component("file.txt"),
Some("file.txt".to_string())
);
assert_eq!(
sanitize_path_component("bad/path"),
Some("badpath".to_string())
);
assert_eq!(
sanitize_path_component("bad\\path"),
Some("badpath".to_string())
);
assert_eq!(sanitize_path_component(""), None);
assert_eq!(sanitize_path_component("."), None);

View file

@ -67,10 +67,7 @@ pub enum SignalType {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum NormalizedPayload {
/// State update payload.
StateUpdate {
node_id: String,
state: Vec<f32>,
},
StateUpdate { node_id: String, state: Vec<f32> },
/// Edge modification payload.
EdgeMod {
source: String,

View file

@ -300,11 +300,7 @@ pub fn weighted_energy_sum_simd(residual_norms: &[f32], weights: &[f32]) -> f32
/// // lanes = [0, 1, 2, 3] (Reflex, Retrieval, Heavy, Human)
/// ```
#[inline]
pub fn batch_lane_assignment_simd(
energies: &[f32],
thresholds: [f32; 4],
lanes: &mut [u8],
) {
pub fn batch_lane_assignment_simd(energies: &[f32], thresholds: [f32; 4], lanes: &mut [u8]) {
debug_assert_eq!(energies.len(), lanes.len());
let len = energies.len();
@ -357,9 +353,7 @@ pub fn batch_lane_assignment_simd(
// Handle remainder
for (i, &e) in remainder_e.iter().enumerate() {
let lane = (e >= t_reflex) as u8
+ (e >= t_retrieval) as u8
+ (e >= t_heavy) as u8;
let lane = (e >= t_reflex) as u8 + (e >= t_retrieval) as u8 + (e >= t_heavy) as u8;
lanes[offset + i] = lane.min(3);
}
}
@ -505,9 +499,7 @@ fn batch_lane_assignment_scalar(energies: &[f32], thresholds: [f32; 4], lanes: &
let t_heavy = thresholds[2];
for (e, l) in energies.iter().zip(lanes.iter_mut()) {
let lane = (*e >= t_reflex) as u8
+ (*e >= t_retrieval) as u8
+ (*e >= t_heavy) as u8;
let lane = (*e >= t_reflex) as u8 + (*e >= t_retrieval) as u8 + (*e >= t_heavy) as u8;
*l = lane.min(3);
}
}
@ -572,7 +564,11 @@ mod tests {
batch_residuals_simd(&sources, &targets, &mut residuals_simd, 64, 16);
batch_residuals_scalar(&sources, &targets, &mut residuals_scalar);
for (i, (&s, &sc)) in residuals_simd.iter().zip(residuals_scalar.iter()).enumerate() {
for (i, (&s, &sc)) in residuals_simd
.iter()
.zip(residuals_scalar.iter())
.enumerate()
{
assert!(approx_eq(s, sc), "at {} got {} expected {}", i, s, sc);
}
}
@ -610,7 +606,12 @@ mod tests {
let result = weighted_energy_sum_simd(&norms, &weights);
let expected = weighted_energy_sum_scalar(&norms, &weights);
assert!(approx_eq(result, expected), "got {} expected {}", result, expected);
assert!(
approx_eq(result, expected),
"got {} expected {}",
result,
expected
);
}
#[test]
@ -692,7 +693,11 @@ mod tests {
let simd_result = compute_residual_norm_sq_simd(&source, &target);
let scalar_result = compute_residual_norm_sq_scalar(&source, &target);
assert!(approx_eq(simd_result, scalar_result),
"simd={} scalar={}", simd_result, scalar_result);
assert!(
approx_eq(simd_result, scalar_result),
"simd={} scalar={}",
simd_result,
scalar_result
);
}
}

View file

@ -507,8 +507,12 @@ mod tests {
// Verify transpose property
for i in 0..m {
for j in 0..n {
assert!(approx_eq(a[i * n + j], b[j * m + i]),
"mismatch at ({}, {})", i, j);
assert!(
approx_eq(a[i * n + j], b[j * m + i]),
"mismatch at ({}, {})",
i,
j
);
}
}
}
@ -564,8 +568,13 @@ mod tests {
// Allow slightly more tolerance for larger matrices due to accumulation
for i in 0..m * n {
assert!((c_simd[i] - c_scalar[i]).abs() < 0.01,
"mismatch at {}: {} vs {}", i, c_simd[i], c_scalar[i]);
assert!(
(c_simd[i] - c_scalar[i]).abs() < 0.01,
"mismatch at {}: {} vs {}",
i,
c_simd[i],
c_scalar[i]
);
}
}
}

Some files were not shown because too many files have changed in this diff Show more