Skip to main content

silicera_lab/
lib.rs

1//! # silicera-lab
2//!
3//! Measurement laboratory: microbenchmarks across memory, integer, float,
4//! branch, and concurrency domains; cache-size workloads; tournaments; and a
5//! terminal UI for live visualization of **real** measurements only.
6//!
7//! Numbers shown in the lab UI come from the measurement engine — never from
8//! hard-coded marketing placeholders.
9
10#![warn(missing_docs)]
11
12pub mod arms;
13pub mod bench;
14pub mod calm;
15pub mod experiments;
16pub mod native_artifacts;
17pub mod profile_gen;
18pub mod silicon_split;
19pub mod single_machine;
20pub mod studies;
21pub mod threads;
22pub mod ui;
23
24pub use arms::{
25    run_concurrency_arms, run_domain_harness, run_float_arms, run_full_harness, run_integer_arms,
26    run_memory_arms, ArmsHarnessConfig, ArmsReport, HarnessSuiteReport,
27};
28pub use bench::{
29    AlignmentBench, BranchBench, CacheTarget, ConcurrencyBench, FloatBench, HostIsaDot,
30    HostIsaReduce, IntegerBench, MemOpBench, MemoryBench, WorkloadKind,
31};
32pub use calm::{run_calm_check, CalmCheckReport};
33pub use experiments::{run_experiment, ExperimentId, ExperimentReport};
34pub use native_artifacts::{
35    default_artifact_kernels, find_workspace_root, run_native_artifact_compare,
36    run_native_artifact_suite, suite_to_workload_entries, ArtifactArm, NativeArtifactReport,
37    NativeArtifactSuite,
38};
39pub use profile_gen::{
40    generate_profile, measure_dispatch_overhead, measure_dispatch_overhead_report,
41    measure_size_classes, size_class_winner_story, DispatchOverheadReport, ProfileGenConfig,
42    SizeClassWinnerStory,
43};
44pub use silicon_split::{
45    read_export, sanitize_export, split_report_paths, split_report_profiles, train_split_profile,
46    write_export, write_machine_b_placeholder, SiliconSplitProtocol,
47};
48pub use single_machine::{
49    merge_artifacts_into_profile, run_single_machine_eval, write_eval_outputs, SingleMachineEval,
50};
51pub use studies::{
52    measure_alignment, measure_placement, spot_check_profile, AlignmentReport, AlignmentSample,
53    PlacementReport, PlacementSample, PlacementStrategy, SpotCheckItem, SpotCheckReport,
54};
55pub use threads::{default_thread_sweep, measure_thread_count_sweep, ThreadCountReport};
56pub use ui::{run_lab_ui, summary_cv, LabSessionRow, LabSessionSummary};
57
58use silicera::measure::MeasurementConfig;
59use silicera::tournament::{Tournament, TournamentConfig, TournamentResult};
60use silicera::variant::{Variant, VariantId};
61use silicera::Result;
62
63/// Run a named microbenchmark tournament with two simple variants.
64pub fn run_simple_tournament(
65    name: &str,
66    baseline: impl Fn() + Send + Sync + 'static,
67    candidate: impl Fn() + Send + Sync + 'static,
68    cfg: MeasurementConfig,
69) -> Result<TournamentResult> {
70    struct FnVariant {
71        id: VariantId,
72        desc: String,
73        f: Box<dyn Fn() + Send + Sync>,
74    }
75    impl Variant for FnVariant {
76        type Output = u64;
77        fn id(&self) -> &VariantId {
78            &self.id
79        }
80        fn description(&self) -> &str {
81            &self.desc
82        }
83        fn run(&self) -> Self::Output {
84            (self.f)();
85            1
86        }
87    }
88
89    let variants = vec![
90        FnVariant {
91            id: VariantId::new("baseline"),
92            desc: "baseline".into(),
93            f: Box::new(baseline),
94        },
95        FnVariant {
96            id: VariantId::new("candidate"),
97            desc: "candidate".into(),
98            f: Box::new(candidate),
99        },
100    ];
101
102    let t = Tournament::new(TournamentConfig {
103        measurement: cfg,
104        baseline_id: VariantId::new("baseline"),
105        ..Default::default()
106    });
107    t.run(name, &variants)
108}
109