Some checks failed
Update All Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Triage Project Sync (#84) / Sync triage project (push) Has been cancelled
release_nightly / notify_on_failure (push) Has been cancelled
release_nightly / check_style (push) Has been cancelled
release_nightly / run_tests_windows (push) Has been cancelled
release_nightly / clippy_windows (push) Has been cancelled
release_nightly / bundle_linux_aarch64 (push) Has been cancelled
release_nightly / bundle_linux_x86_64 (push) Has been cancelled
release_nightly / bundle_mac_aarch64 (push) Has been cancelled
release_nightly / bundle_mac_x86_64 (push) Has been cancelled
release_nightly / bundle_windows_aarch64 (push) Has been cancelled
release_nightly / bundle_windows_x86_64 (push) Has been cancelled
release_nightly / build_nix_linux_x86_64 (push) Has been cancelled
release_nightly / build_nix_mac_aarch64 (push) Has been cancelled
release_nightly / update_nightly_tag (push) Has been cancelled
Hotfix Review Monitor / check-hotfix-reviews (push) Has been cancelled
Stale PR Review Reminder / check-stale-prs (push) Has been cancelled
Update Weekly Top Ranking Issues / update_top_ranking_issues (push) Has been cancelled
Bump collab-staging Tag / update-collab-staging-tag (push) Has been cancelled
compliance_check / scheduled_compliance_check (push) Has been cancelled
Single-commit orphan branch: full zed-industries/zed @ 8c74db0 source tree with a 3-file patch applied (no upstream history). Patch (crates/gpui_linux/src/linux/wayland/): - serial.rs: add SerialKind::KeyboardEnter - client.rs: store wl_keyboard.enter serial; add latest_serial_of() - window.rs: activate() uses keyboard-enter serial (Mutter focus gate) Mutter honors window activation only when the token carries the keyboard- focus serial from wl_keyboard.enter; GPUI used a stale mouse-press serial. See docs/tray-window-focus-wayland.md in logiguard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
147 lines
3.7 KiB
Rust
147 lines
3.7 KiB
Rust
//! Utilities for evaluation and benchmarking.
|
|
|
|
use std::{
|
|
collections::HashMap,
|
|
sync::{Arc, mpsc},
|
|
};
|
|
|
|
fn report_progress(evaluated_count: usize, failed_count: usize, iterations: usize) {
|
|
let passed_count = evaluated_count - failed_count;
|
|
let passed_ratio = if evaluated_count == 0 {
|
|
0.0
|
|
} else {
|
|
passed_count as f64 / evaluated_count as f64
|
|
};
|
|
println!(
|
|
"\r\x1b[KEvaluated {}/{} ({:.2}% passed)",
|
|
evaluated_count,
|
|
iterations,
|
|
passed_ratio * 100.0
|
|
)
|
|
}
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
pub enum OutcomeKind {
|
|
Passed,
|
|
Failed,
|
|
Error,
|
|
}
|
|
|
|
pub trait EvalOutputProcessor {
|
|
type Metadata: 'static + Send;
|
|
fn process(&mut self, output: &EvalOutput<Self::Metadata>);
|
|
fn assert(&mut self);
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct EvalOutput<M> {
|
|
pub outcome: OutcomeKind,
|
|
pub data: String,
|
|
pub metadata: M,
|
|
}
|
|
|
|
impl<M: Default> EvalOutput<M> {
|
|
pub fn passed(message: impl Into<String>) -> Self {
|
|
EvalOutput {
|
|
outcome: OutcomeKind::Passed,
|
|
data: message.into(),
|
|
metadata: M::default(),
|
|
}
|
|
}
|
|
|
|
pub fn failed(message: impl Into<String>) -> Self {
|
|
EvalOutput {
|
|
outcome: OutcomeKind::Failed,
|
|
data: message.into(),
|
|
metadata: M::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct NoProcessor;
|
|
impl EvalOutputProcessor for NoProcessor {
|
|
type Metadata = ();
|
|
|
|
fn process(&mut self, _output: &EvalOutput<Self::Metadata>) {}
|
|
|
|
fn assert(&mut self) {}
|
|
}
|
|
|
|
pub fn eval<P>(
|
|
iterations: usize,
|
|
expected_pass_ratio: f32,
|
|
mut processor: P,
|
|
evalf: impl Fn() -> EvalOutput<P::Metadata> + Send + Sync + 'static,
|
|
) where
|
|
P: EvalOutputProcessor,
|
|
{
|
|
let mut evaluated_count = 0;
|
|
let mut failed_count = 0;
|
|
let evalf = Arc::new(evalf);
|
|
report_progress(evaluated_count, failed_count, iterations);
|
|
|
|
let (tx, rx) = mpsc::channel();
|
|
|
|
let executor = gpui_platform::background_executor();
|
|
let semaphore = Arc::new(smol::lock::Semaphore::new(32));
|
|
let evalf = Arc::new(evalf);
|
|
// Warm the cache once
|
|
let first_output = evalf();
|
|
tx.send(first_output).ok();
|
|
|
|
for _ in 1..iterations {
|
|
let tx = tx.clone();
|
|
let semaphore = semaphore.clone();
|
|
let evalf = evalf.clone();
|
|
executor
|
|
.spawn(async move {
|
|
let _guard = semaphore.acquire().await;
|
|
let output = evalf();
|
|
tx.send(output).ok();
|
|
})
|
|
.detach();
|
|
}
|
|
drop(tx);
|
|
|
|
let mut failed_evals = Vec::new();
|
|
let mut errored_evals = HashMap::new();
|
|
while let Ok(output) = rx.recv() {
|
|
processor.process(&output);
|
|
|
|
match output.outcome {
|
|
OutcomeKind::Passed => {}
|
|
OutcomeKind::Failed => {
|
|
failed_count += 1;
|
|
failed_evals.push(output);
|
|
}
|
|
OutcomeKind::Error => {
|
|
failed_count += 1;
|
|
*errored_evals.entry(output.data).or_insert(0) += 1;
|
|
}
|
|
}
|
|
|
|
evaluated_count += 1;
|
|
report_progress(evaluated_count, failed_count, iterations);
|
|
}
|
|
|
|
let actual_pass_ratio = (iterations - failed_count) as f32 / iterations as f32;
|
|
println!("Actual pass ratio: {}\n", actual_pass_ratio);
|
|
if actual_pass_ratio < expected_pass_ratio {
|
|
for (error, count) in errored_evals {
|
|
println!("Eval errored {} times. Error: {}", count, error);
|
|
}
|
|
|
|
for failed in failed_evals {
|
|
println!("Eval failed");
|
|
println!("{}", failed.data);
|
|
}
|
|
|
|
panic!(
|
|
"Actual pass ratio: {}\nExpected pass ratio: {}",
|
|
actual_pass_ratio, expected_pass_ratio
|
|
);
|
|
}
|
|
|
|
processor.assert();
|
|
}
|