#![allow(dead_code)]
#![allow(unexpected_cfgs)]
use scirs2_core::{
config::{get_config, set_config_value, Config, ConfigValue},
constants::{math, physical},
error::{CoreError, ErrorContext},
random::Random,
};
#[cfg(feature = "memory_management")]
use scirs2_core::memory::{global_buffer_pool, BufferPool, ChunkProcessor, GlobalBufferPool};
#[cfg(feature = "memory_metrics")]
use scirs2_core::memory::metrics::{
format_bytes, take_snapshot, MemoryMetricsCollector, MemorySnapshot,
};
#[cfg(feature = "gpu")]
use scirs2_core::gpu::{GpuBuffer, GpuContext};
use scirs2_core::{
metrics::{Counter, Gauge, Histogram, MetricsRegistry, Timer},
profiling::Profiler as SciRS2Profiler,
validation::check_finite,
};
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::time::{Duration, Instant};
pub struct ScirS2EnhancedProfiler {
config: Config,
rng: Random,
#[cfg(feature = "memory_metrics")]
memory_metrics: Arc<Mutex<MemoryMetricsCollector>>,
#[cfg(feature = "gpu")]
gpu_context: Option<Arc<GpuContext>>,
scirs2_profiler: SciRS2Profiler,
metric_registry: Arc<Mutex<MetricsRegistry>>,
timers: Arc<Mutex<std::collections::HashMap<String, Timer>>>,
counters: Arc<Mutex<std::collections::HashMap<String, Counter>>>,
gauges: Arc<Mutex<std::collections::HashMap<String, Gauge>>>,
histograms: Arc<Mutex<std::collections::HashMap<String, Histogram>>>,
}
impl std::fmt::Debug for ScirS2EnhancedProfiler {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ScirS2EnhancedProfiler")
.field("config", &"<Config>")
.field("rng", &"<Random>")
.field("scirs2_profiler", &"<SciRS2Profiler>")
.field("metric_registry", &"<MetricsRegistry>")
.field("timers", &format!("{} timers", self.timers.lock().len()))
.field(
"counters",
&format!("{} counters", self.counters.lock().len()),
)
.field("gauges", &format!("{} gauges", self.gauges.lock().len()))
.field(
"histograms",
&format!("{} histograms", self.histograms.lock().len()),
)
.finish()
}
}
impl ScirS2EnhancedProfiler {
pub fn new() -> Result<Self, CoreError> {
let mut config = Config::new();
config.set("profiling_enabled", ConfigValue::Bool(true));
config.set("sampling_rate", ConfigValue::Float(1.0));
config.set("memory_tracking", ConfigValue::Bool(true));
config.set("simd_acceleration", ConfigValue::Bool(true));
config.set("parallel_processing", ConfigValue::Bool(true));
config.set("gpu_acceleration", ConfigValue::Bool(true));
config.set("advanced_metrics", ConfigValue::Bool(true));
let scirs2_profiler = SciRS2Profiler::new();
let metric_registry = Arc::new(Mutex::new(MetricsRegistry::new()));
Ok(Self {
config,
rng: Random::default(), #[cfg(feature = "memory_metrics")]
memory_metrics: Arc::new(Mutex::new(MemoryMetricsCollector::new())),
#[cfg(feature = "gpu")]
gpu_context: None,
scirs2_profiler,
metric_registry,
timers: Arc::new(Mutex::new(std::collections::HashMap::new())),
counters: Arc::new(Mutex::new(std::collections::HashMap::new())),
gauges: Arc::new(Mutex::new(std::collections::HashMap::new())),
histograms: Arc::new(Mutex::new(std::collections::HashMap::new())),
})
}
pub fn start_enhanced_profiling(&mut self) -> Result<(), CoreError> {
set_config_value("profiling_enabled", ConfigValue::Bool(true));
set_config_value("memory_tracking", ConfigValue::Bool(true));
#[cfg(feature = "gpu")]
{
match GpuContext::new() {
Ok(ctx) => {
self.gpu_context = Some(Arc::new(ctx));
println!("GPU context initialized for enhanced profiling");
}
Err(_) => {
println!("GPU not available, continuing with CPU-only profiling");
}
}
}
Ok(())
}
pub fn profile_with_sampling<F, T>(
&mut self,
name: &str,
sample_rate: f64,
operation: F,
) -> Result<Option<T>, CoreError>
where
F: FnOnce() -> T,
{
let random_val: f64 = self.rng.gen_range(0.0..1.0);
if random_val < sample_rate {
let start = Instant::now();
let result = operation();
let duration = start.elapsed();
self.record_sampled_operation(name, duration);
Ok(Some(result))
} else {
Ok(None)
}
}
#[cfg(feature = "memory_management")]
pub fn profile_memory_operation<F, T>(&self, name: &str, operation: F) -> Result<T, CoreError>
where
F: FnOnce() -> T,
{
let start = Instant::now();
#[cfg(feature = "memory_metrics")]
let initial_snapshot = take_snapshot();
let result = operation();
let duration = start.elapsed();
#[cfg(feature = "memory_metrics")]
{
let final_snapshot = take_snapshot();
let memory_delta = final_snapshot.total_allocated - initial_snapshot.total_allocated;
self.record_memory_operation(name, duration, memory_delta);
}
#[cfg(not(feature = "memory_metrics"))]
{
self.record_operation(name, duration);
}
Ok(result)
}
#[cfg(feature = "gpu")]
pub fn profile_gpu_operation<F, T>(&self, name: &str, operation: F) -> Result<T, CoreError>
where
F: FnOnce(&GpuContext) -> T,
{
let start = Instant::now();
let result = if let Some(ref gpu_ctx) = self.gpu_context {
operation(gpu_ctx)
} else {
return Err(CoreError::ValidationError(ErrorContext::new(
"GPU context not available".to_string(),
)));
};
let duration = start.elapsed();
self.record_gpu_operation(name, duration);
Ok(result)
}
pub fn analyze_with_constants(&self, operation_name: &str, value: f64) -> PerformanceAnalysis {
let validated_value = match check_finite(value, "performance_value") {
Ok(v) => v,
Err(_) => 0.0, };
let normalized_value = validated_value / math::PI;
let physical_normalized = validated_value / physical::SPEED_OF_LIGHT;
PerformanceAnalysis {
operation_name: operation_name.to_string(),
raw_value: validated_value,
math_normalized: normalized_value,
physics_normalized: physical_normalized,
analysis_timestamp: chrono::Utc::now(),
}
}
pub fn profile_with_comprehensive_metrics<F, T>(
&self,
name: &str,
operation: F,
) -> Result<T, CoreError>
where
F: FnOnce() -> T,
{
let timer_name = format!("timer_{}", name);
{
let mut timers = self.timers.lock();
timers
.entry(timer_name.clone())
.or_insert_with(|| Timer::new(timer_name.clone()));
}
let counter_name = format!("counter_{}", name);
let mut counters = self.counters.lock();
let counter = counters
.entry(counter_name.clone())
.or_insert_with(|| Counter::new(counter_name.clone()));
counter.inc();
drop(counters);
let start = Instant::now();
let result = operation();
let duration = start.elapsed();
let histogram_name = format!("histogram_{}", name);
let mut histograms = self.histograms.lock();
let histogram = histograms
.entry(histogram_name.clone())
.or_insert_with(|| Histogram::new(histogram_name.clone()));
histogram.observe(duration.as_micros() as f64);
drop(histograms);
let gauge_name = format!("gauge_{}", name);
let mut gauges = self.gauges.lock();
let gauge = gauges
.entry(gauge_name.clone())
.or_insert_with(|| Gauge::new(gauge_name.clone()));
gauge.set(duration.as_nanos() as f64);
drop(gauges);
Ok(result)
}
pub fn run_comprehensive_benchmark<F>(
&mut self,
name: &str,
iterations: usize,
operation: F,
) -> Result<BenchmarkResults, CoreError>
where
F: Fn() + Clone,
{
let mut durations = Vec::with_capacity(iterations);
for _ in 0..iterations {
let start = Instant::now();
operation();
let duration = start.elapsed();
durations.push(duration.as_nanos() as f64);
self.profile_with_comprehensive_metrics(name, || {})?;
}
let mean = durations.iter().sum::<f64>() / durations.len() as f64;
let variance =
durations.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / durations.len() as f64;
let std_dev = variance.sqrt();
let validated_mean = check_finite(mean, "benchmark_mean").unwrap_or(0.0);
let validated_std_dev = check_finite(std_dev, "benchmark_std_dev").unwrap_or(0.0);
Ok(BenchmarkResults {
benchmark_name: name.to_string(),
iterations,
mean_duration_ns: validated_mean,
std_deviation_ns: validated_std_dev,
min_duration_ns: durations.iter().fold(f64::INFINITY, |a, &b| a.min(b)),
max_duration_ns: durations.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b)),
total_duration_ns: durations.iter().sum(),
throughput_ops_per_sec: (iterations as f64 * 1_000_000_000.0)
/ durations.iter().sum::<f64>(),
})
}
pub fn get_metrics_summary(&self) -> MetricsSummary {
let mut summary = MetricsSummary {
total_operations: 0,
total_duration_ns: 0.0,
active_timers: Vec::new(),
counter_values: std::collections::HashMap::new(),
gauge_values: std::collections::HashMap::new(),
histogram_stats: std::collections::HashMap::new(),
};
let counters = self.counters.lock();
for (name, counter) in counters.iter() {
summary.counter_values.insert(name.clone(), counter.get());
summary.total_operations += counter.get() as u64;
}
drop(counters);
let gauges = self.gauges.lock();
for (name, gauge) in gauges.iter() {
summary.gauge_values.insert(name.clone(), gauge.get());
}
drop(gauges);
let histograms = self.histograms.lock();
for (name, histogram) in histograms.iter() {
summary.histogram_stats.insert(
name.clone(),
HistogramStats {
count: 1, sum: 0.0, mean: 0.0, },
);
}
drop(histograms);
let timers = self.timers.lock();
for (name, _timer) in timers.iter() {
summary.active_timers.push(name.clone());
}
drop(timers);
summary
}
pub fn export_scirs2_format(&self, path: &str) -> Result<(), CoreError> {
let profiling_data = ScirS2ProfilingData {
config_summary: "SCIRS2 enhanced profiler configuration".to_string(),
#[cfg(feature = "memory_metrics")]
memory_snapshot: {
let metrics = self.memory_metrics.lock();
Some(format!(
"Memory metrics available: {}",
metrics.memory_pool_count()
))
},
#[cfg(not(feature = "memory_metrics"))]
memory_snapshot: None,
#[cfg(feature = "gpu")]
gpu_available: self.gpu_context.is_some(),
#[cfg(not(feature = "gpu"))]
gpu_available: false,
timestamp: chrono::Utc::now(),
};
let json = serde_json::to_string_pretty(&profiling_data).map_err(|e| {
CoreError::ValidationError(ErrorContext::new(format!("Serialization error: {}", e)))
})?;
std::fs::write(path, json).map_err(|e| {
CoreError::ValidationError(ErrorContext::new(format!("IO error: {}", e)))
})?;
Ok(())
}
fn record_sampled_operation(&self, name: &str, duration: Duration) {
#[cfg(feature = "memory_metrics")]
{
let mut metrics = self.memory_metrics.lock();
println!("Sampled operation '{}' took {:?}", name, duration);
}
#[cfg(not(feature = "memory_metrics"))]
{
println!("Sampled operation '{}' took {:?}", name, duration);
}
}
fn record_operation(&self, name: &str, duration: Duration) {
println!("Operation '{}' took {:?}", name, duration);
}
#[cfg(feature = "memory_metrics")]
fn record_memory_operation(&self, name: &str, duration: Duration, memory_delta: i64) {
println!(
"Memory operation '{}' took {:?}, memory delta: {} bytes",
name, duration, memory_delta
);
}
#[cfg(feature = "gpu")]
fn record_gpu_operation(&self, name: &str, duration: Duration) {
println!("GPU operation '{}' took {:?}", name, duration);
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceAnalysis {
pub operation_name: String,
pub raw_value: f64,
pub math_normalized: f64,
pub physics_normalized: f64,
pub analysis_timestamp: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScirS2ProfilingData {
pub config_summary: String, pub memory_snapshot: Option<String>,
pub gpu_available: bool,
pub timestamp: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BenchmarkResults {
pub benchmark_name: String,
pub iterations: usize,
pub mean_duration_ns: f64,
pub std_deviation_ns: f64,
pub min_duration_ns: f64,
pub max_duration_ns: f64,
pub total_duration_ns: f64,
pub throughput_ops_per_sec: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MetricsSummary {
pub total_operations: u64,
pub total_duration_ns: f64,
pub active_timers: Vec<String>,
pub counter_values: std::collections::HashMap<String, u64>,
pub gauge_values: std::collections::HashMap<String, f64>,
pub histogram_stats: std::collections::HashMap<String, HistogramStats>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HistogramStats {
pub count: u64,
pub sum: f64,
pub mean: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AdvancedProfilingConfig {
pub enable_simd_acceleration: bool,
pub enable_parallel_processing: bool,
pub enable_gpu_acceleration: bool,
pub enable_memory_optimization: bool,
pub enable_advanced_metrics: bool,
pub sampling_strategy: SamplingStrategy,
pub validation_level: ValidationLevel,
pub performance_targets: PerformanceTargets,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SamplingStrategy {
Uniform(f64),
Adaptive(f64, f64), Stratified(usize), ImportanceBased(f64), }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ValidationLevel {
None,
Basic,
Comprehensive,
Strict,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceTargets {
pub max_latency_ns: Option<u64>,
pub min_throughput_ops_per_sec: Option<f64>,
pub max_memory_usage_bytes: Option<u64>,
pub target_cpu_utilization: Option<f64>,
}
#[macro_export]
macro_rules! profile_scirs2_sampling {
($profiler:expr, $name:expr, $rate:expr, $block:block) => {{
$profiler.profile_with_sampling($name, $rate, || $block)
}};
}
#[cfg(feature = "memory_management")]
#[macro_export]
macro_rules! profile_scirs2_memory {
($profiler:expr, $name:expr, $block:block) => {{
$profiler.profile_memory_operation($name, || $block)
}};
}
#[cfg(feature = "gpu")]
#[macro_export]
macro_rules! profile_scirs2_gpu {
($profiler:expr, $name:expr, $block:expr) => {{
$profiler.profile_gpu_operation($name, |ctx| $block)
}};
}
#[macro_export]
macro_rules! profile_scirs2_comprehensive {
($profiler:expr, $name:expr, $block:block) => {{
$profiler.profile_with_comprehensive_metrics($name, || $block)
}};
}
#[macro_export]
macro_rules! benchmark_scirs2 {
($profiler:expr, $name:expr, $iterations:expr, $operation:expr) => {{
$profiler.run_comprehensive_benchmark($name, $iterations, $operation)
}};
}
#[macro_export]
macro_rules! collect_scirs2_metrics {
($profiler:expr) => {{
$profiler.get_metrics_summary()
}};
}
#[macro_export]
macro_rules! profile_scirs2_validated {
($profiler:expr, $name:expr, $value:expr, $operation:block) => {{
let analysis = $profiler.analyze_with_constants($name, $value);
$profiler.profile_with_comprehensive_metrics($name, || $operation)?;
Ok(analysis)
}};
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn test_scirs2_enhanced_profiler_creation() {
let profiler = ScirS2EnhancedProfiler::new();
assert!(profiler.is_ok());
}
#[test]
fn test_start_enhanced_profiling() {
let mut profiler = ScirS2EnhancedProfiler::new().unwrap();
let result = profiler.start_enhanced_profiling();
assert!(result.is_ok());
}
#[test]
fn test_profile_with_sampling() {
let mut profiler = ScirS2EnhancedProfiler::new().unwrap();
let result = profiler.profile_with_sampling("test_sampling", 1.0, || 42);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Some(42));
let result = profiler.profile_with_sampling("test_sampling", 0.0, || 42);
assert!(result.is_ok());
assert_eq!(result.unwrap(), None);
}
#[test]
fn test_analyze_with_constants() {
let profiler = ScirS2EnhancedProfiler::new().unwrap();
let analysis = profiler.analyze_with_constants("test_operation", 100.0);
assert_eq!(analysis.operation_name, "test_operation");
assert_eq!(analysis.raw_value, 100.0);
assert!(analysis.math_normalized > 0.0);
assert!(analysis.physics_normalized > 0.0);
}
#[test]
#[cfg(feature = "memory_management")]
fn test_profile_memory_operation() {
let profiler = ScirS2EnhancedProfiler::new().unwrap();
let result = profiler.profile_memory_operation("test_memory", || {
let _vec: Vec<u8> = vec![0; 1024];
42
});
assert!(result.is_ok());
assert_eq!(result.unwrap(), 42);
}
#[test]
fn test_export_scirs2_format() {
let profiler = ScirS2EnhancedProfiler::new().unwrap();
let temp_path = std::env::temp_dir().join("test_scirs2_export.json");
let result = profiler.export_scirs2_format(temp_path.to_str().unwrap());
assert!(result.is_ok());
assert!(temp_path.exists());
let _ = std::fs::remove_file(temp_path);
}
#[test]
fn test_scirs2_sampling_macro() {
let mut profiler = ScirS2EnhancedProfiler::new().unwrap();
let result = profile_scirs2_sampling!(profiler, "macro_test", 1.0, { 42 });
assert!(result.is_ok());
assert_eq!(result.unwrap(), Some(42));
}
#[test]
fn test_comprehensive_metrics_profiling() {
let profiler = ScirS2EnhancedProfiler::new().unwrap();
let result = profiler.profile_with_comprehensive_metrics("test_comprehensive", || {
std::thread::sleep(Duration::from_millis(1));
42
});
assert!(result.is_ok());
assert_eq!(result.unwrap(), 42);
let metrics = profiler.get_metrics_summary();
assert!(metrics
.counter_values
.contains_key("counter_test_comprehensive"));
assert!(metrics
.gauge_values
.contains_key("gauge_test_comprehensive"));
assert!(metrics
.histogram_stats
.contains_key("histogram_test_comprehensive"));
}
#[test]
fn test_comprehensive_benchmark() {
let mut profiler = ScirS2EnhancedProfiler::new().unwrap();
let operation = || {
std::thread::sleep(Duration::from_micros(10));
};
let result = profiler.run_comprehensive_benchmark("test_benchmark", 5, operation);
assert!(result.is_ok());
let benchmark_results = result.unwrap();
assert_eq!(benchmark_results.benchmark_name, "test_benchmark");
assert_eq!(benchmark_results.iterations, 5);
assert!(benchmark_results.mean_duration_ns > 0.0);
assert!(benchmark_results.throughput_ops_per_sec > 0.0);
}
#[test]
fn test_enhanced_validation() {
let profiler = ScirS2EnhancedProfiler::new().unwrap();
let analysis = profiler.analyze_with_constants("test_validation", 100.0);
assert_eq!(analysis.operation_name, "test_validation");
assert_eq!(analysis.raw_value, 100.0);
assert!(analysis.math_normalized > 0.0);
let analysis = profiler.analyze_with_constants("test_nan", f64::NAN);
assert_eq!(analysis.raw_value, 0.0); }
#[test]
fn test_advanced_macros() {
let profiler = ScirS2EnhancedProfiler::new().unwrap();
let result = profile_scirs2_comprehensive!(profiler, "macro_comprehensive", {
std::thread::sleep(Duration::from_micros(1));
"test_result"
});
assert!(result.is_ok());
assert_eq!(result.unwrap(), "test_result");
let metrics = collect_scirs2_metrics!(profiler);
assert!(metrics
.counter_values
.contains_key("counter_macro_comprehensive"));
}
}