1#![cfg_attr(
22 not(any(feature = "tensorflow", feature = "pytorch", feature = "jax")),
23 allow(unexpected_cfgs)
24)]
25
26pub mod core;
28
29pub mod ndarray_comparisons;
31pub mod reporting;
32
33#[cfg(feature = "pytorch")]
35pub mod pytorch_comparisons;
36
37#[cfg(feature = "tensorflow")]
38pub mod tensorflow_comparisons;
39
40#[cfg(feature = "jax")]
41pub mod jax_comparisons;
42
43#[cfg(feature = "numpy_baseline")]
44pub mod numpy_comparisons;
45
46pub mod comparisons {
48 pub use crate::core::*;
55
56 pub use crate::ndarray_comparisons::*;
58
59 #[cfg(feature = "pytorch")]
61 pub use crate::pytorch_comparisons::*;
62
63 #[cfg(feature = "tensorflow")]
64 pub use crate::tensorflow_comparisons::*;
65
66 #[cfg(feature = "jax")]
67 pub use crate::jax_comparisons::*;
68
69 #[cfg(feature = "numpy_baseline")]
70 pub use crate::numpy_comparisons::*;
71
72 pub use crate::reporting::*;
74}
75
76pub mod advanced_analysis;
78pub mod benchmark_analysis;
79pub mod benchmark_cache;
80pub mod benchmark_comparison;
81pub mod benchmark_validation;
82pub mod benchmarks;
83pub mod cached_runner;
84pub mod ci_integration;
85pub mod custom_ops_benchmarks;
86pub mod distributed_training;
87pub mod edge_deployment;
88pub mod hardware_benchmarks;
89pub mod html_reporting;
90pub mod metrics;
91pub mod mobile_benchmarks;
92pub mod model_benchmarks;
93pub mod performance_dashboards;
94pub mod precision_benchmarks;
95pub mod regression_detection;
96pub mod scalability;
97pub mod scirs2_benchmarks;
98pub mod system_info;
99pub mod utils;
100pub mod visualization;
101pub mod wasm_benchmarks;
102
103pub use benchmarks::{
105 AdvancedSystemsBenchmarkSuite, AutoTuningBench, BackwardPassBench, DataLoaderThroughputBench,
106 ErrorDiagnosticsBench, GradientComputeBench, MatmulBench, SIMDGNNBench, TensorArithmeticBench,
107 TensorCreationBench, VectorizedMetricsBench,
108};
109
110pub use core::{ComparisonResult, ComparisonRunner, PerformanceAnalyzer};
112
113pub use reporting::{
115 benchmark_and_analyze, benchmark_and_analyze_to, benchmark_and_compare,
116 generate_master_comparison_report, generate_master_comparison_report_to,
117 run_all_comparison_suites, run_comparison_benchmarks, run_extended_benchmarks,
118};
119
120pub use metrics::{CpuStats, MemoryStats, MetricsCollector, PerformanceReport, SystemMetrics};
122pub use utils::{
123 DataGenerator,
124 Distribution,
125 EnhancedBenchResult,
126 EnhancedBenchSuite,
127 Environment,
128 EnvironmentInfo,
129 Formatter,
130 MemoryMonitor,
131 ParallelBenchRunner,
132 Timer,
133 TimingStats,
135 ValidationResult,
136 Validator,
137};
138
139pub use model_benchmarks::{ModelBenchmarkSuite, ResNetBlockBench, TransformerBlockBench};
141
142pub use hardware_benchmarks::{
144 CPUGPUComparisonBench, MemoryBandwidthBench, MultiGPUBench, ThermalThrottlingBench,
145};
146pub use scalability::ScalabilityTestSuite;
147
148pub use precision_benchmarks::{MixedPrecisionTrainingBench, PruningBench, QuantizationBench};
150
151pub use custom_ops_benchmarks::{ConvolutionOperation, CustomOpBench, FFTOperation};
153pub use edge_deployment::{BatteryLifeBench, EdgeInferenceBench, EdgeMemoryBench};
154pub use mobile_benchmarks::{ARMOptimizationBench, MobileGPUBench, MobilePlatformBench};
155pub use wasm_benchmarks::{BrowserSpecificBench, WASMPerformanceBench, WebDeploymentBench};
156
157pub use scirs2_benchmarks::{
159 AdvancedNeuralNetworkBench, AdvancedOptimizerBench, GraphNeuralNetworkBench,
160 SciRS2BenchmarkSuite, SciRS2MathBench, SciRS2RandomBench, SpatialVisionBench,
161 TimeSeriesAnalysisBench,
162};
163
164pub use advanced_analysis::{AdaptiveBenchmarking, AdvancedAnalyzer};
166pub use benchmark_analysis::{
167 BenchmarkAnalyzer, BottleneckAnalysis, PerformanceAnalysis, PerformanceRating,
168};
169pub use benchmark_validation::{BenchmarkValidator, NumericalAccuracy, ValidationConfig};
170pub use ci_integration::{CIBenchmarkRunner, CIConfig, NotificationConfig};
171pub use html_reporting::{HtmlReportGenerator, Theme};
172pub use performance_dashboards::{DashboardConfig, PerformanceDashboard};
173pub use regression_detection::{AdvancedRegressionDetector, RegressionAnalysis};
174pub use system_info::{BenchmarkEnvironment, SystemInfo, SystemInfoCollector};
175pub use visualization::{ChartType, VisualizationGenerator};
176
177use criterion::{BenchmarkId, Criterion, Throughput};
178use std::time::Duration;
179
180pub trait Benchmarkable {
182 type Input;
183 type Output;
184
185 fn setup(&mut self, size: usize) -> Self::Input;
187
188 fn run(&mut self, input: &Self::Input) -> Self::Output;
190
191 fn flops(&self, size: usize) -> usize {
193 size
195 }
196
197 fn bytes_accessed(&self, size: usize) -> usize {
199 size * std::mem::size_of::<f32>()
201 }
202}
203
204#[derive(Debug, Clone)]
206pub struct BenchConfig {
207 pub name: String,
209
210 pub sizes: Vec<usize>,
212
213 pub dtypes: Vec<torsh_core::dtype::DType>,
215
216 pub warmup_time: Duration,
218
219 pub measurement_time: Duration,
221
222 pub measure_memory: bool,
224
225 pub measure_throughput: bool,
227
228 pub metadata: std::collections::HashMap<String, String>,
230}
231
232impl Default for BenchConfig {
233 fn default() -> Self {
234 Self {
235 name: "default".to_string(),
236 sizes: vec![64, 256, 1024, 4096],
237 dtypes: vec![torsh_core::dtype::DType::F32],
238 warmup_time: Duration::from_millis(100),
239 measurement_time: Duration::from_secs(1),
240 measure_memory: false,
241 measure_throughput: true,
242 metadata: std::collections::HashMap::new(),
243 }
244 }
245}
246
247impl BenchConfig {
248 pub fn new(name: &str) -> Self {
250 Self {
251 name: name.to_string(),
252 ..Default::default()
253 }
254 }
255
256 pub fn with_sizes(mut self, sizes: Vec<usize>) -> Self {
258 self.sizes = sizes;
259 self
260 }
261
262 pub fn with_dtypes(mut self, dtypes: Vec<torsh_core::dtype::DType>) -> Self {
264 self.dtypes = dtypes;
265 self
266 }
267
268 pub fn with_memory_measurement(mut self) -> Self {
270 self.measure_memory = true;
271 self
272 }
273
274 pub fn with_timing(mut self, warmup: Duration, measurement: Duration) -> Self {
276 self.warmup_time = warmup;
277 self.measurement_time = measurement;
278 self
279 }
280
281 pub fn with_metadata(mut self, key: &str, value: &str) -> Self {
283 self.metadata.insert(key.to_string(), value.to_string());
284 self
285 }
286}
287
288#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
290pub struct BenchResult {
291 pub name: String,
293
294 pub size: usize,
296
297 pub dtype: torsh_core::dtype::DType,
299
300 pub mean_time_ns: f64,
302
303 pub std_dev_ns: f64,
305
306 pub throughput: Option<f64>,
308
309 pub memory_usage: Option<usize>,
311
312 pub peak_memory: Option<usize>,
314
315 pub metrics: std::collections::HashMap<String, f64>,
317}
318
319impl BenchResult {
320 pub fn gflops(&self, flops_per_op: usize) -> Option<f64> {
322 self.throughput.map(|tps| tps * flops_per_op as f64 / 1e9)
323 }
324
325 pub fn memory_bandwidth_gbps(&self, bytes_per_op: usize) -> Option<f64> {
327 self.throughput.map(|tps| tps * bytes_per_op as f64 / 1e9)
328 }
329}
330
331#[macro_export]
333macro_rules! benchmark {
334 ($name:expr, $setup:expr, $run:expr) => {{
335 struct SimpleBench<S, R> {
336 setup_fn: S,
337 run_fn: R,
338 }
339
340 impl<S, R, I, O> $crate::Benchmarkable for SimpleBench<S, R>
341 where
342 S: FnMut(usize) -> I,
343 R: FnMut(&I) -> O,
344 {
345 type Input = I;
346 type Output = O;
347
348 fn setup(&mut self, size: usize) -> <Self as $crate::Benchmarkable>::Input {
349 (self.setup_fn)(size)
350 }
351
352 fn run(
353 &mut self,
354 input: &<Self as $crate::Benchmarkable>::Input,
355 ) -> <Self as $crate::Benchmarkable>::Output {
356 (self.run_fn)(input)
357 }
358 }
359
360 SimpleBench {
361 setup_fn: $setup,
362 run_fn: $run,
363 }
364 }};
365}
366
367pub struct BenchRunner {
369 criterion: Criterion,
370 configs: Vec<BenchConfig>,
371 results: Vec<BenchResult>,
372}
373
374impl BenchRunner {
375 pub fn new() -> Self {
377 Self {
378 criterion: Criterion::default()
379 .warm_up_time(Duration::from_millis(100))
380 .measurement_time(Duration::from_secs(1)),
381 configs: Vec::new(),
382 results: Vec::new(),
383 }
384 }
385
386 pub fn add_config(mut self, config: BenchConfig) -> Self {
388 self.configs.push(config);
389 self
390 }
391
392 pub fn run_benchmark<B: Benchmarkable>(&mut self, mut bench: B, config: &BenchConfig) {
394 let mut group = self.criterion.benchmark_group(&config.name);
395 group.warm_up_time(config.warmup_time);
396 group.measurement_time(config.measurement_time);
397
398 for &size in &config.sizes {
399 for &dtype in &config.dtypes {
400 let bench_id = BenchmarkId::new(format!("{}_{:?}", config.name, dtype), size);
401
402 if config.measure_throughput {
403 let bytes_per_op = bench.bytes_accessed(size);
404 group.throughput(Throughput::Bytes(bytes_per_op as u64));
405 }
406
407 group.bench_with_input(bench_id, &size, |b, &size| {
408 let input = bench.setup(size);
409
410 b.iter(|| bench.run(&input));
411 });
412 }
413 }
414
415 group.finish();
416 }
417
418 pub fn results(&self) -> &[BenchResult] {
420 &self.results
421 }
422
423 pub fn export_csv(&self, path: &str) -> std::io::Result<()> {
425 use std::io::Write;
426 let mut file = std::fs::File::create(path)?;
427
428 writeln!(
429 file,
430 "name,size,dtype,mean_time_ns,std_dev_ns,throughput,memory_usage"
431 )?;
432
433 for result in &self.results {
434 writeln!(
435 file,
436 "{},{},{:?},{},{},{:?},{:?}",
437 result.name,
438 result.size,
439 result.dtype,
440 result.mean_time_ns,
441 result.std_dev_ns,
442 result.throughput,
443 result.memory_usage
444 )?;
445 }
446
447 Ok(())
448 }
449
450 pub fn generate_report(&self, output_dir: &str) -> std::io::Result<()> {
452 std::fs::create_dir_all(output_dir)?;
453
454 let report_path = format!("{}/benchmark_report.html", output_dir);
455 let mut file = std::fs::File::create(report_path)?;
456
457 use std::io::Write;
458 writeln!(file, "<!DOCTYPE html>")?;
459 writeln!(
460 file,
461 "<html><head><title>ToRSh Benchmark Report</title></head><body>"
462 )?;
463 writeln!(file, "<h1>ToRSh Benchmark Report</h1>")?;
464
465 writeln!(file, "<table border='1'>")?;
467 writeln!(file, "<tr><th>Benchmark</th><th>Size</th><th>Type</th><th>Time (μs)</th><th>Throughput</th></tr>")?;
468
469 for result in &self.results {
470 writeln!(
471 file,
472 "<tr><td>{}</td><td>{}</td><td>{:?}</td><td>{:.2}</td><td>{:.2}</td></tr>",
473 result.name,
474 result.size,
475 result.dtype,
476 result.mean_time_ns / 1000.0,
477 result.throughput.unwrap_or(0.0)
478 )?;
479 }
480
481 writeln!(file, "</table>")?;
482 writeln!(file, "</body></html>")?;
483
484 Ok(())
485 }
486}
487
488impl Default for BenchRunner {
489 fn default() -> Self {
490 Self::new()
491 }
492}
493
494pub mod prelude {
496 pub use super::{benchmark, BenchConfig, BenchResult, BenchRunner};
497 pub use super::{BenchmarkAnalyzer, SystemInfoCollector};
498 pub use crate::benchmark_analysis::{BottleneckAnalysis, PerformanceAnalysis};
499 pub use crate::core::{ComparisonResult, ComparisonRunner, PerformanceAnalyzer};
500 pub use crate::system_info::{BenchmarkEnvironment, SystemInfo};
501 pub use crate::Benchmarkable;
502 pub use criterion::{BenchmarkId, Criterion, Throughput};
503 pub use std::hint::black_box;
504
505 pub use crate::utils::{
507 Distribution, EnhancedBenchResult, EnhancedBenchSuite, EnvironmentInfo, Formatter,
508 MemoryMonitor, ParallelBenchRunner, Timer, TimingStats, ValidationResult, Validator,
509 };
510}