feat: vendor midstream and sublinear-time-solver libraries

Add ruvnet/midstream (AIMDS real-time inference) and
ruvnet/sublinear-time-solver (sublinear optimization algorithms)
as vendored dependencies under vendor/.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
ruv
2026-03-02 23:32:45 -05:00
parent 14902e6b4e
commit e91bb8a1d5
1600 changed files with 1852646 additions and 0 deletions
@@ -0,0 +1,612 @@
#!/usr/bin/env python3
"""
Python Inference Example for Temporal Neural Solver
This script demonstrates how to use the Temporal Neural Solver models
for ultra-low latency inference in Python applications.
"""
import time
import argparse
import json
from pathlib import Path
from typing import Dict, List, Tuple, Optional, Union
import warnings
warnings.filterwarnings('ignore')
try:
import numpy as np
import onnxruntime as ort
import matplotlib.pyplot as plt
from dataclasses import dataclass
except ImportError as e:
print(f"❌ Missing dependencies: {e}")
print("Install with: pip install numpy onnxruntime matplotlib")
exit(1)
@dataclass
class PredictionResult:
"""Structured prediction result"""
prediction: np.ndarray
latency_ms: float
confidence: Optional[float] = None
certificate_error: Optional[float] = None
metadata: Optional[Dict] = None
class TemporalNeuralSolver:
"""
Python interface for Temporal Neural Solver inference
This class provides a high-level interface for running inference
with the breakthrough sub-millisecond neural network.
"""
def __init__(
self,
model_path: str,
optimize: bool = True,
enable_profiling: bool = False
):
"""
Initialize the Temporal Neural Solver
Args:
model_path: Path to ONNX model file
optimize: Enable ONNX Runtime optimizations
enable_profiling: Enable performance profiling
"""
self.model_path = Path(model_path)
self.enable_profiling = enable_profiling
if not self.model_path.exists():
raise FileNotFoundError(f"Model file not found: {model_path}")
# Configure ONNX Runtime for optimal performance
self.session_options = ort.SessionOptions()
if optimize:
self.session_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
self.session_options.execution_mode = ort.ExecutionMode.ORT_SEQUENTIAL
self.session_options.intra_op_num_threads = 1 # Single thread for latency
if enable_profiling:
self.session_options.enable_profiling = True
# Load model with optimal providers
providers = self._get_optimal_providers()
try:
self.session = ort.InferenceSession(
str(self.model_path),
sess_options=self.session_options,
providers=providers
)
except Exception as e:
print(f"❌ Failed to load model: {e}")
raise
# Get model metadata
self.input_info = self.session.get_inputs()[0]
self.output_info = self.session.get_outputs()[0]
print(f"✅ Temporal Neural Solver loaded: {self.model_path.name}")
print(f" Input: {self.input_info.name} {self.input_info.shape}")
print(f" Output: {self.output_info.name} {self.output_info.shape}")
print(f" Providers: {self.session.get_providers()}")
# Warmup for stable performance
self._warmup()
def _get_optimal_providers(self) -> List[str]:
"""Get optimal execution providers based on availability"""
available_providers = ort.get_available_providers()
optimal_providers = []
# Prefer GPU providers if available
if 'TensorrtExecutionProvider' in available_providers:
optimal_providers.append('TensorrtExecutionProvider')
if 'CUDAExecutionProvider' in available_providers:
optimal_providers.append('CUDAExecutionProvider')
# Always include CPU as fallback
optimal_providers.append('CPUExecutionProvider')
return optimal_providers
def _warmup(self, num_runs: int = 100) -> None:
"""Warmup the model for stable benchmarking"""
print(f"🔥 Warming up model ({num_runs} runs)...")
# Generate dummy input matching model expectations
dummy_input = self._generate_dummy_input()
input_dict = {self.input_info.name: dummy_input}
for _ in range(num_runs):
_ = self.session.run(None, input_dict)
print("✅ Warmup complete")
def _generate_dummy_input(self) -> np.ndarray:
"""Generate dummy input for warmup and testing"""
# Parse input shape, handling dynamic dimensions
shape = []
for dim in self.input_info.shape:
if isinstance(dim, str) or dim == -1:
# Dynamic dimension - use reasonable default
if len(shape) == 0: # Batch dimension
shape.append(1)
elif len(shape) == 1: # Sequence dimension
shape.append(10)
else: # Feature dimension
shape.append(4)
else:
shape.append(dim)
return np.random.randn(*shape).astype(np.float32)
def predict(
self,
sequence: Union[np.ndarray, List[List[float]]],
return_latency: bool = True,
validate_input: bool = True
) -> PredictionResult:
"""
Run prediction on input sequence
Args:
sequence: Input time series data [timesteps, features] or [batch, timesteps, features]
return_latency: Whether to measure and return latency
validate_input: Whether to validate input format
Returns:
PredictionResult with prediction and metadata
"""
# Convert to numpy array if needed
if isinstance(sequence, list):
sequence = np.array(sequence, dtype=np.float32)
# Validate and reshape input
if validate_input:
sequence = self._validate_and_reshape_input(sequence)
# Prepare input dictionary
input_dict = {self.input_info.name: sequence}
# Run inference with optional timing
if return_latency:
start_time = time.perf_counter()
outputs = self.session.run(None, input_dict)
end_time = time.perf_counter()
latency_ms = (end_time - start_time) * 1000
else:
outputs = self.session.run(None, input_dict)
latency_ms = 0.0
# Extract prediction (first batch if batched)
prediction = outputs[0]
if prediction.ndim > 1:
prediction = prediction[0]
return PredictionResult(
prediction=prediction,
latency_ms=latency_ms,
metadata={
'model': str(self.model_path.name),
'input_shape': list(sequence.shape),
'output_shape': list(outputs[0].shape)
}
)
def _validate_and_reshape_input(self, sequence: np.ndarray) -> np.ndarray:
"""Validate and reshape input to match model expectations"""
# Ensure float32 dtype
if sequence.dtype != np.float32:
sequence = sequence.astype(np.float32)
# Handle different input shapes
if sequence.ndim == 1:
# Single timestep: [features] -> [1, 1, features]
sequence = sequence.reshape(1, 1, -1)
elif sequence.ndim == 2:
# Sequence: [timesteps, features] -> [1, timesteps, features]
sequence = sequence.reshape(1, *sequence.shape)
elif sequence.ndim == 3:
# Already correct: [batch, timesteps, features]
pass
else:
raise ValueError(f"Invalid input shape: {sequence.shape}")
return sequence
def predict_batch(
self,
sequences: List[np.ndarray],
batch_size: int = 32
) -> List[PredictionResult]:
"""
Run batch prediction on multiple sequences
Args:
sequences: List of input sequences
batch_size: Batch size for processing
Returns:
List of PredictionResult objects
"""
results = []
for i in range(0, len(sequences), batch_size):
batch = sequences[i:i + batch_size]
# Stack into batch tensor
batch_tensor = np.stack([
self._validate_and_reshape_input(seq)[0] for seq in batch
], axis=0)
# Run batch prediction
input_dict = {self.input_info.name: batch_tensor}
start_time = time.perf_counter()
outputs = self.session.run(None, input_dict)
end_time = time.perf_counter()
total_latency_ms = (end_time - start_time) * 1000
per_sample_latency = total_latency_ms / len(batch)
# Create results for each item in batch
for j, prediction in enumerate(outputs[0]):
results.append(PredictionResult(
prediction=prediction,
latency_ms=per_sample_latency,
metadata={
'model': str(self.model_path.name),
'batch_size': len(batch),
'batch_index': j
}
))
return results
def benchmark(
self,
num_samples: int = 1000,
warmup_samples: int = 100,
return_raw_latencies: bool = False
) -> Dict:
"""
Run comprehensive performance benchmark
Args:
num_samples: Number of inference samples
warmup_samples: Number of warmup samples
return_raw_latencies: Whether to include raw latency data
Returns:
Dictionary with benchmark statistics
"""
print(f"📊 Running benchmark ({num_samples} samples)...")
# Generate test data
dummy_input = self._generate_dummy_input()
input_dict = {self.input_info.name: dummy_input}
# Warmup
print(f"🔥 Warmup ({warmup_samples} samples)...")
for _ in range(warmup_samples):
_ = self.session.run(None, input_dict)
# Benchmark
print(f"⏱️ Measuring latency...")
latencies = []
errors = 0
for i in range(num_samples):
if i % 100 == 0 and i > 0:
print(f" Progress: {i}/{num_samples}")
try:
start_time = time.perf_counter()
outputs = self.session.run(None, input_dict)
end_time = time.perf_counter()
latency_ms = (end_time - start_time) * 1000
latencies.append(latency_ms)
# Basic output validation
if not outputs or outputs[0] is None:
errors += 1
except Exception as e:
errors += 1
print(f" Error in sample {i}: {e}")
latencies = np.array(latencies)
# Calculate comprehensive statistics
stats = {
'num_samples': len(latencies),
'errors': errors,
'success_rate': (len(latencies) / num_samples) * 100,
'latency_ms': {
'mean': float(np.mean(latencies)),
'std': float(np.std(latencies)),
'min': float(np.min(latencies)),
'max': float(np.max(latencies)),
'median': float(np.median(latencies)),
'p90': float(np.percentile(latencies, 90)),
'p95': float(np.percentile(latencies, 95)),
'p99': float(np.percentile(latencies, 99)),
'p99_9': float(np.percentile(latencies, 99.9)),
'p99_99': float(np.percentile(latencies, 99.99)),
},
'throughput_pps': 1000 / np.mean(latencies),
'success_criteria': {
'sub_millisecond_p99_9': float(np.percentile(latencies, 99.9)) < 1.0,
'target_0_9ms_p99_9': float(np.percentile(latencies, 99.9)) < 0.9,
'high_success_rate': (len(latencies) / num_samples) * 100 > 99.0
}
}
if return_raw_latencies:
stats['raw_latencies'] = latencies.tolist()
print(f"✅ Benchmark complete!")
print(f" Mean latency: {stats['latency_ms']['mean']:.3f}ms")
print(f" P99.9 latency: {stats['latency_ms']['p99_9']:.3f}ms")
print(f" Throughput: {stats['throughput_pps']:.0f} pps")
print(f" Sub-ms P99.9: {'' if stats['success_criteria']['sub_millisecond_p99_9'] else ''}")
print(f" Target 0.9ms: {'' if stats['success_criteria']['target_0_9ms_p99_9'] else ''}")
return stats
def get_model_info(self) -> Dict:
"""Get detailed model information"""
return {
'model_path': str(self.model_path),
'model_size_mb': self.model_path.stat().st_size / (1024 * 1024),
'inputs': [{
'name': inp.name,
'shape': inp.shape,
'type': inp.type
} for inp in self.session.get_inputs()],
'outputs': [{
'name': out.name,
'shape': out.shape,
'type': out.type
} for out in self.session.get_outputs()],
'providers': self.session.get_providers(),
'onnx_version': ort.__version__
}
def generate_sample_trajectory(length: int = 10, noise_level: float = 0.1) -> np.ndarray:
"""Generate a sample trajectory for demonstration"""
trajectory = []
for i in range(length):
t = i / length
# Position with sinusoidal motion + noise
x = np.sin(2 * np.pi * t) + np.random.normal(0, noise_level)
y = np.cos(2 * np.pi * t) + np.random.normal(0, noise_level)
# Velocity (derivatives)
vx = 2 * np.pi * np.cos(2 * np.pi * t) + np.random.normal(0, noise_level * 0.5)
vy = -2 * np.pi * np.sin(2 * np.pi * t) + np.random.normal(0, noise_level * 0.5)
trajectory.append([x, y, vx, vy])
return np.array(trajectory, dtype=np.float32)
def plot_trajectory_and_prediction(
input_trajectory: np.ndarray,
prediction: np.ndarray,
title: str = "Trajectory Prediction"
) -> None:
"""Visualize input trajectory and prediction"""
try:
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# Plot trajectory in 2D space
ax1.plot(input_trajectory[:, 0], input_trajectory[:, 1], 'b-o',
label='Input Trajectory', alpha=0.7)
ax1.plot(prediction[0], prediction[1], 'ro',
label='Predicted Next Point', markersize=10)
ax1.set_xlabel('X Position')
ax1.set_ylabel('Y Position')
ax1.set_title('Spatial Trajectory')
ax1.legend()
ax1.grid(True, alpha=0.3)
ax1.axis('equal')
# Plot time series
time_steps = range(len(input_trajectory))
for i, label in enumerate(['X', 'Y', 'VX', 'VY']):
ax2.plot(time_steps, input_trajectory[:, i],
label=f'{label} (input)', alpha=0.7)
# Show prediction as next timestep
next_time = len(input_trajectory)
for i, label in enumerate(['X', 'Y', 'VX', 'VY']):
ax2.plot(next_time, prediction[i], 'o',
label=f'{label} (pred)', markersize=8)
ax2.set_xlabel('Time Step')
ax2.set_ylabel('Value')
ax2.set_title('Time Series Features')
ax2.legend()
ax2.grid(True, alpha=0.3)
plt.suptitle(title, fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()
except Exception as e:
print(f"⚠️ Plotting failed: {e}")
def demo_basic_usage(model_path: str) -> None:
"""Demonstrate basic usage of the Temporal Neural Solver"""
print("🎯 Basic Usage Demo")
print("="*40)
# Initialize solver
solver = TemporalNeuralSolver(model_path)
# Generate sample data
trajectory = generate_sample_trajectory(length=10)
print(f"📊 Generated trajectory with shape: {trajectory.shape}")
# Single prediction
result = solver.predict(trajectory)
print(f"✅ Prediction Results:")
print(f" Prediction: {result.prediction}")
print(f" Latency: {result.latency_ms:.3f}ms")
print(f" Sub-millisecond: {'' if result.latency_ms < 1.0 else ''}")
# Visualize if matplotlib available
plot_trajectory_and_prediction(trajectory, result.prediction,
"Basic Usage - Trajectory Prediction")
def demo_batch_processing(model_path: str) -> None:
"""Demonstrate batch processing capabilities"""
print("\n📦 Batch Processing Demo")
print("="*40)
solver = TemporalNeuralSolver(model_path)
# Generate multiple trajectories
trajectories = [generate_sample_trajectory(length=10) for _ in range(5)]
print(f"📊 Generated {len(trajectories)} trajectories")
# Batch prediction
start_time = time.time()
results = solver.predict_batch(trajectories, batch_size=32)
total_time = time.time() - start_time
print(f"✅ Batch Results:")
print(f" Total trajectories: {len(results)}")
print(f" Total time: {total_time*1000:.3f}ms")
print(f" Average latency per sample: {np.mean([r.latency_ms for r in results]):.3f}ms")
print(f" Throughput: {len(results)/total_time:.0f} predictions/second")
def demo_benchmark(model_path: str) -> None:
"""Demonstrate comprehensive benchmarking"""
print("\n📊 Benchmark Demo")
print("="*40)
solver = TemporalNeuralSolver(model_path)
# Run benchmark
stats = solver.benchmark(num_samples=1000, return_raw_latencies=True)
# Display results
print(f"\n🏆 Benchmark Summary:")
print(f" Samples: {stats['num_samples']}")
print(f" Success rate: {stats['success_rate']:.1f}%")
print(f" Mean latency: {stats['latency_ms']['mean']:.3f}ms")
print(f" P99.9 latency: {stats['latency_ms']['p99_9']:.3f}ms")
print(f" Throughput: {stats['throughput_pps']:.0f} pps")
print(f"\n🎯 Success Criteria:")
for criterion, passed in stats['success_criteria'].items():
status = "" if passed else ""
print(f" {criterion}: {status}")
# Plot latency distribution
if 'raw_latencies' in stats:
try:
plt.figure(figsize=(10, 6))
latencies = stats['raw_latencies']
plt.subplot(1, 2, 1)
plt.hist(latencies, bins=50, alpha=0.7, edgecolor='black')
plt.axvline(stats['latency_ms']['p99_9'], color='red', linestyle='--',
label=f'P99.9: {stats["latency_ms"]["p99_9"]:.3f}ms')
plt.axvline(0.9, color='green', linestyle='--', label='Target: 0.9ms')
plt.xlabel('Latency (ms)')
plt.ylabel('Frequency')
plt.title('Latency Distribution')
plt.legend()
plt.grid(True, alpha=0.3)
plt.subplot(1, 2, 2)
plt.plot(latencies[:100], alpha=0.7) # First 100 samples
plt.xlabel('Sample Number')
plt.ylabel('Latency (ms)')
plt.title('Latency Time Series')
plt.grid(True, alpha=0.3)
plt.suptitle('Benchmark Results - Latency Analysis', fontsize=14, fontweight='bold')
plt.tight_layout()
plt.show()
except Exception as e:
print(f"⚠️ Plotting failed: {e}")
def main():
"""Main demonstration function"""
parser = argparse.ArgumentParser(
description="Python Inference Example for Temporal Neural Solver"
)
parser.add_argument(
"model_path",
help="Path to ONNX model file"
)
parser.add_argument(
"--demo",
choices=["basic", "batch", "benchmark", "all"],
default="all",
help="Which demo to run"
)
parser.add_argument(
"--no-plots",
action="store_true",
help="Disable matplotlib plots"
)
args = parser.parse_args()
# Disable plotting if requested
if args.no_plots:
def dummy_plot(*args, **kwargs):
pass
global plot_trajectory_and_prediction
plot_trajectory_and_prediction = dummy_plot
print("🚀 Temporal Neural Solver - Python Inference Example")
print("="*60)
print(f"Model: {args.model_path}")
print(f"Demo: {args.demo}")
print()
# Check if model exists
if not Path(args.model_path).exists():
print(f"❌ Model file not found: {args.model_path}")
print("Please ensure the ONNX model file exists.")
return
try:
# Run requested demos
if args.demo in ["basic", "all"]:
demo_basic_usage(args.model_path)
if args.demo in ["batch", "all"]:
demo_batch_processing(args.model_path)
if args.demo in ["benchmark", "all"]:
demo_benchmark(args.model_path)
print("\n🎉 Demo complete!")
print("\n💡 Next steps:")
print("- Integrate the TemporalNeuralSolver class into your application")
print("- Customize input preprocessing for your data")
print("- Monitor latency in production environments")
print("- Use batch processing for higher throughput")
except Exception as e:
print(f"❌ Demo failed: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()
@@ -0,0 +1,595 @@
#!/usr/bin/env python3
"""
Real-Time Inference Demo for Temporal Neural Solver
This script demonstrates real-time inference capabilities of the Temporal Neural Solver,
simulating time-critical applications like HFT, robotics, and autonomous systems.
"""
import time
import threading
import queue
import argparse
import json
from pathlib import Path
from typing import Dict, List, Optional, Callable
from dataclasses import dataclass, field
from collections import deque
import warnings
warnings.filterwarnings('ignore')
try:
import numpy as np
import onnxruntime as ort
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import pandas as pd
except ImportError as e:
print(f"❌ Missing dependencies: {e}")
print("Install with: pip install numpy onnxruntime matplotlib pandas")
exit(1)
@dataclass
class RealTimeEvent:
"""Real-time event with timestamp and data"""
timestamp: float
data: np.ndarray
event_id: int
metadata: Dict = field(default_factory=dict)
@dataclass
class PredictionEvent:
"""Prediction result event"""
timestamp: float
prediction: np.ndarray
latency_ms: float
event_id: int
success: bool
metadata: Dict = field(default_factory=dict)
class RealTimeDataGenerator:
"""Generates realistic real-time data streams"""
def __init__(self, frequency_hz: float = 100.0, noise_level: float = 0.1):
self.frequency_hz = frequency_hz
self.noise_level = noise_level
self.start_time = time.time()
self.event_counter = 0
def generate_market_data(self) -> RealTimeEvent:
"""Generate synthetic high-frequency trading data"""
current_time = time.time()
elapsed = current_time - self.start_time
# Simulate price movements with trend and volatility
base_price = 100.0
trend = 0.001 * elapsed # Slow upward trend
volatility = 0.5 * np.sin(2 * np.pi * elapsed * 0.1) # Cyclical volatility
noise = np.random.normal(0, self.noise_level)
# Create OHLCV-like data over small time windows
price = base_price + trend + volatility + noise
volume = 1000 + 500 * np.abs(noise)
# Simulate order book features
bid_ask_spread = 0.01 + 0.005 * np.abs(noise)
market_depth = 10000 + 2000 * noise
data = np.array([price, volume, bid_ask_spread, market_depth], dtype=np.float32)
self.event_counter += 1
return RealTimeEvent(
timestamp=current_time,
data=data,
event_id=self.event_counter,
metadata={"type": "market_data", "symbol": "DEMO/USD"}
)
def generate_sensor_data(self) -> RealTimeEvent:
"""Generate synthetic robotics/autonomous vehicle sensor data"""
current_time = time.time()
elapsed = current_time - self.start_time
# Simulate vehicle motion in a circular path
angular_freq = 0.5 # rad/s
radius = 5.0
# Position
x = radius * np.cos(angular_freq * elapsed) + np.random.normal(0, self.noise_level * 0.1)
y = radius * np.sin(angular_freq * elapsed) + np.random.normal(0, self.noise_level * 0.1)
# Velocity
vx = -radius * angular_freq * np.sin(angular_freq * elapsed) + np.random.normal(0, self.noise_level * 0.05)
vy = radius * angular_freq * np.cos(angular_freq * elapsed) + np.random.normal(0, self.noise_level * 0.05)
data = np.array([x, y, vx, vy], dtype=np.float32)
self.event_counter += 1
return RealTimeEvent(
timestamp=current_time,
data=data,
event_id=self.event_counter,
metadata={"type": "sensor_data", "vehicle_id": "demo_vehicle"}
)
def generate_iot_data(self) -> RealTimeEvent:
"""Generate synthetic IoT edge device data"""
current_time = time.time()
elapsed = current_time - self.start_time
# Simulate environmental sensors with daily patterns
time_of_day = (elapsed % 86400) / 86400 # Normalize to [0, 1] for daily cycle
# Temperature with daily cycle
base_temp = 20.0
daily_variation = 10.0 * np.sin(2 * np.pi * time_of_day - np.pi/2) # Peak at noon
temp = base_temp + daily_variation + np.random.normal(0, self.noise_level)
# Humidity (inverse correlation with temperature)
humidity = 60.0 - 0.5 * daily_variation + np.random.normal(0, self.noise_level * 5)
# Light level (solar pattern)
light = max(0, 1000 * np.sin(np.pi * time_of_day)) + np.random.normal(0, self.noise_level * 10)
# Motion detection (binary with some activity patterns)
motion_prob = 0.1 + 0.2 * np.sin(4 * np.pi * time_of_day) # More active during day
motion = 1.0 if np.random.random() < motion_prob else 0.0
data = np.array([temp, humidity, light, motion], dtype=np.float32)
self.event_counter += 1
return RealTimeEvent(
timestamp=current_time,
data=data,
event_id=self.event_counter,
metadata={"type": "iot_data", "device_id": "demo_sensor"}
)
class RealTimePredictor:
"""Real-time inference engine with sub-millisecond latency"""
def __init__(self, model_path: str, sequence_length: int = 10):
self.model_path = Path(model_path)
self.sequence_length = sequence_length
# Configure ONNX Runtime for minimal latency
self.session_options = ort.SessionOptions()
self.session_options.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
self.session_options.execution_mode = ort.ExecutionMode.ORT_SEQUENTIAL
self.session_options.intra_op_num_threads = 1
# Load model
if self.model_path.exists():
self.session = ort.InferenceSession(
str(self.model_path),
sess_options=self.session_options,
providers=['CPUExecutionProvider']
)
self.input_name = self.session.get_inputs()[0].name
print(f"✅ Model loaded: {self.model_path}")
else:
print(f"⚠️ Model not found: {self.model_path}, using synthetic predictor")
self.session = None
# Sliding window buffer for sequence data
self.data_buffer = deque(maxlen=self.sequence_length)
# Performance tracking
self.prediction_count = 0
self.total_latency = 0.0
self.max_latency = 0.0
self.latency_history = deque(maxlen=1000)
def add_data_point(self, data: np.ndarray) -> bool:
"""Add data point to sliding window buffer"""
self.data_buffer.append(data)
return len(self.data_buffer) == self.sequence_length
def predict(self, event: RealTimeEvent) -> PredictionEvent:
"""Run real-time prediction on event data"""
# Add to buffer
buffer_ready = self.add_data_point(event.data)
if not buffer_ready:
# Not enough data yet - return dummy prediction
return PredictionEvent(
timestamp=time.time(),
prediction=np.zeros(4, dtype=np.float32),
latency_ms=0.0,
event_id=event.event_id,
success=False,
metadata={"error": "insufficient_data"}
)
# Prepare input sequence
sequence = np.array(list(self.data_buffer), dtype=np.float32)
sequence = sequence.reshape(1, self.sequence_length, -1)
# Run inference with timing
start_time = time.perf_counter()
try:
if self.session is not None:
# Real model inference
outputs = self.session.run(None, {self.input_name: sequence})
prediction = outputs[0][0]
else:
# Synthetic prediction for demo
time.sleep(0.0008) # Simulate 0.8ms processing time
prediction = sequence[0, -1] + np.random.normal(0, 0.01, 4)
end_time = time.perf_counter()
latency_ms = (end_time - start_time) * 1000
# Update statistics
self.prediction_count += 1
self.total_latency += latency_ms
self.max_latency = max(self.max_latency, latency_ms)
self.latency_history.append(latency_ms)
return PredictionEvent(
timestamp=end_time,
prediction=prediction,
latency_ms=latency_ms,
event_id=event.event_id,
success=True,
metadata={
"avg_latency_ms": self.total_latency / self.prediction_count,
"max_latency_ms": self.max_latency
}
)
except Exception as e:
end_time = time.perf_counter()
latency_ms = (end_time - start_time) * 1000
return PredictionEvent(
timestamp=end_time,
prediction=np.zeros(4, dtype=np.float32),
latency_ms=latency_ms,
event_id=event.event_id,
success=False,
metadata={"error": str(e)}
)
def get_statistics(self) -> Dict:
"""Get current performance statistics"""
if self.prediction_count == 0:
return {"predictions": 0}
latencies = list(self.latency_history)
return {
"predictions": self.prediction_count,
"avg_latency_ms": self.total_latency / self.prediction_count,
"max_latency_ms": self.max_latency,
"current_p99_ms": np.percentile(latencies, 99) if latencies else 0,
"current_p99_9_ms": np.percentile(latencies, 99.9) if latencies else 0,
"sub_millisecond_rate": (np.array(latencies) < 1.0).mean() * 100 if latencies else 0,
}
class RealTimeSimulator:
"""Real-time inference simulation orchestrator"""
def __init__(
self,
model_path: str,
scenario: str = "market",
frequency_hz: float = 100.0,
duration_seconds: float = 60.0
):
self.scenario = scenario
self.frequency_hz = frequency_hz
self.duration_seconds = duration_seconds
# Initialize components
self.data_generator = RealTimeDataGenerator(frequency_hz)
self.predictor = RealTimePredictor(model_path)
# Event queues
self.input_queue = queue.Queue(maxsize=1000)
self.output_queue = queue.Queue(maxsize=1000)
# Monitoring
self.events_processed = 0
self.simulation_start_time = None
self.running = False
# Results storage
self.results = {
"events": [],
"predictions": [],
"statistics": {}
}
def data_producer_thread(self):
"""Producer thread generating real-time data"""
interval = 1.0 / self.frequency_hz
while self.running:
start_time = time.time()
# Generate data based on scenario
if self.scenario == "market":
event = self.data_generator.generate_market_data()
elif self.scenario == "robotics":
event = self.data_generator.generate_sensor_data()
elif self.scenario == "iot":
event = self.data_generator.generate_iot_data()
else:
event = self.data_generator.generate_sensor_data()
try:
self.input_queue.put(event, timeout=0.001)
except queue.Full:
print("⚠️ Input queue full, dropping event")
# Maintain frequency
elapsed = time.time() - start_time
sleep_time = max(0, interval - elapsed)
if sleep_time > 0:
time.sleep(sleep_time)
def inference_consumer_thread(self):
"""Consumer thread running inference"""
while self.running:
try:
event = self.input_queue.get(timeout=0.1)
prediction = self.predictor.predict(event)
self.output_queue.put(prediction)
self.events_processed += 1
# Check for latency violations
if prediction.success and prediction.latency_ms > 1.0:
print(f"⚠️ Latency violation: {prediction.latency_ms:.3f}ms")
except queue.Empty:
continue
def monitoring_thread(self):
"""Monitoring thread for real-time statistics"""
while self.running:
time.sleep(1.0) # Update every second
stats = self.predictor.get_statistics()
elapsed = time.time() - self.simulation_start_time
print(f"📊 [{elapsed:6.1f}s] Events: {self.events_processed:5d} | "
f"Avg: {stats.get('avg_latency_ms', 0):.3f}ms | "
f"P99.9: {stats.get('current_p99_9_ms', 0):.3f}ms | "
f"Sub-ms: {stats.get('sub_millisecond_rate', 0):.1f}%")
def run_simulation(self):
"""Run the complete real-time simulation"""
print(f"🚀 Starting real-time simulation")
print(f" Scenario: {self.scenario}")
print(f" Frequency: {self.frequency_hz} Hz")
print(f" Duration: {self.duration_seconds}s")
print(f" Expected events: {int(self.frequency_hz * self.duration_seconds)}")
print()
self.simulation_start_time = time.time()
self.running = True
# Start threads
producer = threading.Thread(target=self.data_producer_thread, daemon=True)
consumer = threading.Thread(target=self.inference_consumer_thread, daemon=True)
monitor = threading.Thread(target=self.monitoring_thread, daemon=True)
producer.start()
consumer.start()
monitor.start()
# Run for specified duration
time.sleep(self.duration_seconds)
# Stop simulation
self.running = False
print("\n🛑 Stopping simulation...")
# Wait for threads to finish
producer.join(timeout=1.0)
consumer.join(timeout=1.0)
monitor.join(timeout=1.0)
# Collect final results
final_stats = self.predictor.get_statistics()
self.results["statistics"] = final_stats
print("\n✅ Simulation complete!")
return self.results
def print_summary(self):
"""Print simulation summary"""
stats = self.results["statistics"]
print("\n📋 REAL-TIME SIMULATION SUMMARY")
print("=" * 50)
print(f"Scenario: {self.scenario}")
print(f"Events processed: {self.events_processed}")
print(f"Total predictions: {stats.get('predictions', 0)}")
print(f"Processing rate: {stats.get('predictions', 0) / self.duration_seconds:.1f} pps")
print(f"\n⏱️ Latency Performance:")
print(f" Average: {stats.get('avg_latency_ms', 0):.3f}ms")
print(f" Maximum: {stats.get('max_latency_ms', 0):.3f}ms")
print(f" P99: {stats.get('current_p99_ms', 0):.3f}ms")
print(f" P99.9: {stats.get('current_p99_9_ms', 0):.3f}ms")
print(f"\n🎯 Success Criteria:")
sub_ms_rate = stats.get('sub_millisecond_rate', 0)
p99_9 = stats.get('current_p99_9_ms', 0)
print(f" Sub-millisecond rate: {sub_ms_rate:.1f}% {'' if sub_ms_rate > 95 else ''}")
print(f" P99.9 < 1.0ms: {p99_9:.3f}ms {'' if p99_9 < 1.0 else ''}")
print(f" P99.9 < 0.9ms: {p99_9:.3f}ms {'' if p99_9 < 0.9 else ''}")
# Application-specific metrics
if self.scenario == "market":
print(f"\n💰 HFT Application:")
print(f" Decision latency: {p99_9:.3f}ms")
print(f" Market opportunity: {'✅ Captured' if p99_9 < 0.5 else '⚠️ Marginal' if p99_9 < 1.0 else '❌ Missed'}")
elif self.scenario == "robotics":
print(f"\n🤖 Robotics Application:")
print(f" Control loop latency: {p99_9:.3f}ms")
print(f" Real-time control: {'✅ Achieved' if p99_9 < 1.0 else '❌ Failed'}")
elif self.scenario == "iot":
print(f"\n📱 IoT Edge Application:")
print(f" Edge inference: {p99_9:.3f}ms")
print(f" Battery efficient: {'✅ Yes' if stats.get('avg_latency_ms', 0) < 0.5 else '⚠️ Moderate'}")
def create_live_visualization(simulator: RealTimeSimulator):
"""Create live visualization of real-time inference"""
try:
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
fig.suptitle(f'Real-Time Inference Monitor - {simulator.scenario.title()}', fontsize=14)
# Data storage for plotting
times = deque(maxlen=200)
latencies = deque(maxlen=200)
predictions = deque(maxlen=200)
throughput = deque(maxlen=200)
def update_plots(frame):
if not simulator.running:
return
current_time = time.time() - simulator.simulation_start_time
stats = simulator.predictor.get_statistics()
# Update data
times.append(current_time)
latencies.append(stats.get('current_p99_9_ms', 0))
throughput.append(stats.get('predictions', 0) / max(current_time, 1))
# Get recent prediction if available
try:
prediction = simulator.output_queue.get_nowait()
predictions.append(np.mean(prediction.prediction))
except queue.Empty:
if predictions:
predictions.append(predictions[-1])
else:
predictions.append(0)
# Clear and redraw plots
for ax in axes.flat:
ax.clear()
# Plot 1: Latency over time
if times and latencies:
axes[0, 0].plot(list(times), list(latencies), 'b-', alpha=0.7)
axes[0, 0].axhline(y=1.0, color='r', linestyle='--', label='1ms target')
axes[0, 0].axhline(y=0.9, color='g', linestyle='--', label='0.9ms target')
axes[0, 0].set_ylabel('P99.9 Latency (ms)')
axes[0, 0].set_title('Latency Performance')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)
# Plot 2: Throughput
if times and throughput:
axes[0, 1].plot(list(times), list(throughput), 'g-', alpha=0.7)
axes[0, 1].set_ylabel('Predictions/Second')
axes[0, 1].set_title('Throughput')
axes[0, 1].grid(True, alpha=0.3)
# Plot 3: Prediction values
if times and predictions:
axes[1, 0].plot(list(times), list(predictions), 'orange', alpha=0.7)
axes[1, 0].set_ylabel('Prediction Value')
axes[1, 0].set_title('Prediction Trend')
axes[1, 0].grid(True, alpha=0.3)
# Plot 4: Statistics summary
axes[1, 1].axis('off')
if stats:
stats_text = f"""Real-Time Statistics:
Events: {simulator.events_processed:,}
Predictions: {stats.get('predictions', 0):,}
Avg Latency: {stats.get('avg_latency_ms', 0):.3f}ms
Max Latency: {stats.get('max_latency_ms', 0):.3f}ms
P99.9 Latency: {stats.get('current_p99_9_ms', 0):.3f}ms
Sub-ms Rate: {stats.get('sub_millisecond_rate', 0):.1f}%
Status: {'🟢 REAL-TIME' if stats.get('current_p99_9_ms', 0) < 1.0 else '🟡 MARGINAL' if stats.get('current_p99_9_ms', 0) < 2.0 else '🔴 DELAYED'}"""
axes[1, 1].text(0.1, 0.9, stats_text, fontsize=10, verticalalignment='top',
fontfamily='monospace')
plt.tight_layout()
# Create animation
ani = FuncAnimation(fig, update_plots, interval=100, cache_frame_data=False)
return ani
except Exception as e:
print(f"⚠️ Visualization failed: {e}")
return None
def main():
"""Main entry point for real-time demo"""
parser = argparse.ArgumentParser(description="Real-Time Inference Demo")
parser.add_argument("--model", default="system_b.onnx", help="Path to ONNX model")
parser.add_argument("--scenario", choices=["market", "robotics", "iot"], default="market",
help="Application scenario")
parser.add_argument("--frequency", type=float, default=100.0, help="Data frequency (Hz)")
parser.add_argument("--duration", type=float, default=30.0, help="Simulation duration (seconds)")
parser.add_argument("--visualize", action="store_true", help="Show live visualization")
parser.add_argument("--save-results", help="Save results to JSON file")
args = parser.parse_args()
print("⚡ Temporal Neural Solver - Real-Time Inference Demo")
print("=" * 60)
# Create simulator
simulator = RealTimeSimulator(
model_path=args.model,
scenario=args.scenario,
frequency_hz=args.frequency,
duration_seconds=args.duration
)
# Setup visualization if requested
animation = None
if args.visualize:
try:
animation = create_live_visualization(simulator)
# Start visualization in background
plt.ion()
plt.show()
except Exception as e:
print(f"⚠️ Visualization setup failed: {e}")
# Run simulation
try:
results = simulator.run_simulation()
simulator.print_summary()
# Save results if requested
if args.save_results:
with open(args.save_results, 'w') as f:
json.dump(results, f, indent=2, default=str)
print(f"\n📄 Results saved: {args.save_results}")
# Keep visualization alive
if animation and args.visualize:
print("\n🖥️ Close the plot window to exit...")
plt.ioff()
plt.show()
except KeyboardInterrupt:
print("\n⚠️ Simulation interrupted by user")
simulator.running = False
except Exception as e:
print(f"\n❌ Simulation failed: {e}")
import traceback
traceback.print_exc()
print("\n🎉 Real-time demo complete!")
if __name__ == "__main__":
main()
@@ -0,0 +1,546 @@
//! Rust Integration Example for Temporal Neural Solver
//!
//! This example demonstrates how to integrate the Temporal Neural Solver
//! into Rust applications for ultra-low latency inference.
use std::time::Instant;
use std::path::Path;
use serde::{Deserialize, Serialize};
use nalgebra::{DVector, DMatrix};
// Re-export from the main crate
use temporal_neural_net::{
models::{SystemA, SystemB, ModelTrait},
config::{Config, ModelConfig, InferenceConfig},
data::{TimeSeriesData, WindowedSample},
inference::{Predictor, Prediction},
export::ONNXExporter,
error::{Result, TemporalNeuralError},
};
/// Configuration for the Rust integration example
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExampleConfig {
/// Model configuration
pub model: ModelConfig,
/// Inference configuration
pub inference: InferenceConfig,
/// Example-specific settings
pub example: ExampleSettings,
}
/// Example-specific settings
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExampleSettings {
/// Number of benchmark iterations
pub benchmark_iterations: usize,
/// Whether to enable detailed logging
pub enable_logging: bool,
/// Output directory for results
pub output_dir: String,
}
impl Default for ExampleSettings {
fn default() -> Self {
Self {
benchmark_iterations: 10000,
enable_logging: true,
output_dir: "output".to_string(),
}
}
}
/// Performance metrics for benchmarking
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceMetrics {
/// Number of samples processed
pub num_samples: usize,
/// Mean latency in milliseconds
pub mean_latency_ms: f64,
/// Standard deviation of latency
pub std_latency_ms: f64,
/// P99.9 latency in milliseconds
pub p99_9_latency_ms: f64,
/// Throughput in predictions per second
pub throughput_pps: f64,
/// Success rate percentage
pub success_rate: f64,
/// Whether sub-millisecond target was achieved
pub sub_millisecond_achieved: bool,
}
/// Rust-native Temporal Neural Solver interface
pub struct RustTemporalSolver {
/// The underlying neural network model
model: Box<dyn ModelTrait>,
/// Inference engine
predictor: Predictor,
/// Configuration
config: Config,
}
impl RustTemporalSolver {
/// Create a new Temporal Neural Solver instance
pub fn new(config_path: &str) -> Result<Self> {
// Load configuration
let config = Config::from_file(config_path)?;
// Create model based on configuration
let model: Box<dyn ModelTrait> = match config.model.system_type.as_str() {
"A" => Box::new(SystemA::new(config.model.clone())?),
"B" => Box::new(SystemB::new(config.model.clone())?),
_ => return Err(TemporalNeuralError::ConfigurationError {
field: "system_type".to_string(),
message: "Must be 'A' or 'B'".to_string(),
}),
};
// Create predictor
let predictor = Predictor::new(*model.clone(), config.inference.clone())?;
println!("✅ Rust Temporal Neural Solver initialized");
println!(" System type: {}", config.model.system_type);
println!(" Architecture: {}", config.model.architecture);
Ok(Self {
model,
predictor,
config,
})
}
/// Run a single prediction with timing
pub fn predict_timed(&self, input: &DVector<f64>) -> Result<(Prediction, f64)> {
let start = Instant::now();
let prediction = self.predictor.predict(input)?;
let elapsed = start.elapsed();
let latency_ms = elapsed.as_secs_f64() * 1000.0;
Ok((prediction, latency_ms))
}
/// Generate synthetic test data for demonstration
pub fn generate_test_data(&self, sequence_length: usize) -> DVector<f64> {
let mut data = Vec::new();
for i in 0..sequence_length {
let t = i as f64 / sequence_length as f64;
// Generate sinusoidal trajectory with noise
let x = (2.0 * std::f64::consts::PI * t).sin() + self.random_noise(0.1);
let y = (2.0 * std::f64::consts::PI * t).cos() + self.random_noise(0.1);
let vx = 2.0 * std::f64::consts::PI * (2.0 * std::f64::consts::PI * t).cos() + self.random_noise(0.05);
let vy = -2.0 * std::f64::consts::PI * (2.0 * std::f64::consts::PI * t).sin() + self.random_noise(0.05);
data.extend_from_slice(&[x, y, vx, vy]);
}
DVector::from_vec(data)
}
/// Generate random noise (simplified - in practice use proper RNG)
fn random_noise(&self, std_dev: f64) -> f64 {
// Simplified Box-Muller transform for demonstration
use std::f64::consts::PI;
static mut U1: f64 = 0.0;
static mut U2: f64 = 0.0;
static mut CACHED: bool = false;
unsafe {
if CACHED {
CACHED = false;
std_dev * (-2.0 * U1.ln()).sqrt() * (2.0 * PI * U2).sin()
} else {
U1 = fastrand::f64();
U2 = fastrand::f64();
CACHED = true;
std_dev * (-2.0 * U1.ln()).sqrt() * (2.0 * PI * U2).cos()
}
}
}
/// Run comprehensive benchmark
pub fn benchmark(&self, num_iterations: usize) -> Result<PerformanceMetrics> {
println!("🏃‍♂️ Running Rust benchmark ({} iterations)...", num_iterations);
let mut latencies = Vec::with_capacity(num_iterations);
let mut successes = 0;
// Warmup
println!("🔥 Warming up...");
for _ in 0..100 {
let test_data = self.generate_test_data(10);
let _ = self.predictor.predict(&test_data);
}
// Benchmark loop
println!("⏱️ Measuring performance...");
let benchmark_start = Instant::now();
for i in 0..num_iterations {
if i % 1000 == 0 && i > 0 {
println!(" Progress: {}/{}", i, num_iterations);
}
let test_data = self.generate_test_data(10);
match self.predict_timed(&test_data) {
Ok((_, latency_ms)) => {
latencies.push(latency_ms);
successes += 1;
},
Err(_) => {
// Count failures but continue
}
}
}
let total_time = benchmark_start.elapsed();
// Calculate statistics
if latencies.is_empty() {
return Err(TemporalNeuralError::BenchmarkError {
message: "No successful predictions in benchmark".to_string(),
});
}
latencies.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mean_latency = latencies.iter().sum::<f64>() / latencies.len() as f64;
let variance = latencies.iter()
.map(|x| (x - mean_latency).powi(2))
.sum::<f64>() / latencies.len() as f64;
let std_latency = variance.sqrt();
let p99_9_index = ((latencies.len() as f64 * 0.999) as usize).min(latencies.len() - 1);
let p99_9_latency = latencies[p99_9_index];
let throughput = latencies.len() as f64 / total_time.as_secs_f64();
let success_rate = (successes as f64 / num_iterations as f64) * 100.0;
let metrics = PerformanceMetrics {
num_samples: latencies.len(),
mean_latency_ms: mean_latency,
std_latency_ms: std_latency,
p99_9_latency_ms: p99_9_latency,
throughput_pps: throughput,
success_rate,
sub_millisecond_achieved: p99_9_latency < 1.0,
};
println!("✅ Benchmark complete!");
println!(" Mean latency: {:.3}ms", metrics.mean_latency_ms);
println!(" P99.9 latency: {:.3}ms", metrics.p99_9_latency_ms);
println!(" Throughput: {:.0} pps", metrics.throughput_pps);
println!(" Success rate: {:.1}%", metrics.success_rate);
println!(" Sub-millisecond: {}", if metrics.sub_millisecond_achieved { "" } else { "" });
Ok(metrics)
}
/// Export model to ONNX format
pub fn export_to_onnx(&self, output_path: &str) -> Result<()> {
println!("📤 Exporting to ONNX: {}", output_path);
let exporter = ONNXExporter::new();
match self.config.model.system_type.as_str() {
"A" => {
if let Ok(system_a) = self.model.as_any().downcast_ref::<SystemA>() {
exporter.export_system_a(system_a, output_path)?;
}
},
"B" => {
if let Ok(system_b) = self.model.as_any().downcast_ref::<SystemB>() {
exporter.export_system_b(system_b, output_path)?;
}
},
_ => return Err(TemporalNeuralError::ExportError {
message: "Unknown system type for export".to_string(),
}),
}
println!("✅ ONNX export complete: {}", output_path);
Ok(())
}
/// Save benchmark results to file
pub fn save_benchmark_results(&self, metrics: &PerformanceMetrics, path: &str) -> Result<()> {
let json = serde_json::to_string_pretty(metrics)
.map_err(|e| TemporalNeuralError::SerializationError {
message: format!("Failed to serialize metrics: {}", e),
})?;
std::fs::write(path, json)
.map_err(|e| TemporalNeuralError::IoError {
operation: "write_benchmark_results".to_string(),
path: path.into(),
source: e,
})?;
println!("📄 Benchmark results saved: {}", path);
Ok(())
}
}
/// Demonstration functions
pub mod demo {
use super::*;
/// Basic usage demonstration
pub fn basic_usage() -> Result<()> {
println!("🎯 Basic Usage Demo");
println!("==================");
// Load configuration (you would typically load from file)
let config = Config::default_system_b();
// Create solver
let solver = RustTemporalSolver::new("configs/B_temporal_solver.yaml")
.or_else(|_| {
// Fallback to in-memory config if file doesn't exist
println!("⚠️ Config file not found, using default configuration");
Ok(RustTemporalSolver {
model: Box::new(SystemB::new(config.model.clone())?),
predictor: Predictor::new(
SystemB::new(config.model.clone())?,
config.inference.clone()
)?,
config,
})
})?;
// Generate test data
let test_input = solver.generate_test_data(10);
println!("📊 Generated test input with {} elements", test_input.len());
// Run single prediction
let (prediction, latency) = solver.predict_timed(&test_input)?;
println!("✅ Prediction complete:");
println!(" Result: {:?}", prediction.value.as_slice());
println!(" Latency: {:.3}ms", latency);
println!(" Certificate error: {:.6}", prediction.certificate.error);
println!(" Sub-millisecond: {}", if latency < 1.0 { "" } else { "" });
Ok(())
}
/// Performance benchmark demonstration
pub fn benchmark_demo() -> Result<()> {
println!("\n📊 Benchmark Demo");
println!("=================");
let config = Config::default_system_b();
let solver = RustTemporalSolver::new("configs/B_temporal_solver.yaml")
.or_else(|_| {
println!("⚠️ Using default configuration");
Ok(RustTemporalSolver {
model: Box::new(SystemB::new(config.model.clone())?),
predictor: Predictor::new(
SystemB::new(config.model.clone())?,
config.inference.clone()
)?,
config,
})
})?;
// Run benchmark
let metrics = solver.benchmark(5000)?; // Reduced for demo
// Save results
solver.save_benchmark_results(&metrics, "rust_benchmark_results.json")?;
println!("\n🏆 Benchmark Summary:");
println!(" Samples: {}", metrics.num_samples);
println!(" Mean latency: {:.3}ms ± {:.3}ms", metrics.mean_latency_ms, metrics.std_latency_ms);
println!(" P99.9 latency: {:.3}ms", metrics.p99_9_latency_ms);
println!(" Throughput: {:.0} predictions/second", metrics.throughput_pps);
println!(" Success rate: {:.1}%", metrics.success_rate);
println!("\n🎯 Success Criteria:");
println!(" Sub-millisecond P99.9: {}", if metrics.sub_millisecond_achieved { "" } else { "" });
println!(" Target 0.9ms P99.9: {}", if metrics.p99_9_latency_ms < 0.9 { "" } else { "" });
println!(" High success rate: {}", if metrics.success_rate > 99.0 { "" } else { "" });
Ok(())
}
/// ONNX export demonstration
pub fn onnx_export_demo() -> Result<()> {
println!("\n📤 ONNX Export Demo");
println!("===================");
let config = Config::default_system_b();
let solver = RustTemporalSolver::new("configs/B_temporal_solver.yaml")
.or_else(|_| {
println!("⚠️ Using default configuration");
Ok(RustTemporalSolver {
model: Box::new(SystemB::new(config.model.clone())?),
predictor: Predictor::new(
SystemB::new(config.model.clone())?,
config.inference.clone()
)?,
config,
})
})?;
// Export to ONNX
solver.export_to_onnx("temporal_solver_rust_export.onnx")?;
println!("✅ ONNX export demonstration complete");
println!(" File: temporal_solver_rust_export.onnx");
println!(" Ready for deployment with ONNX Runtime");
Ok(())
}
/// Real-time simulation demonstration
pub fn realtime_simulation() -> Result<()> {
println!("\n⚡ Real-time Simulation Demo");
println!("===========================");
let config = Config::default_system_b();
let solver = RustTemporalSolver::new("configs/B_temporal_solver.yaml")
.or_else(|_| {
println!("⚠️ Using default configuration");
Ok(RustTemporalSolver {
model: Box::new(SystemB::new(config.model.clone())?),
predictor: Predictor::new(
SystemB::new(config.model.clone())?,
config.inference.clone()
)?,
config,
})
})?;
println!("🎮 Simulating real-time inference loop...");
let mut total_latency = 0.0;
let mut max_latency = 0.0;
let simulation_steps = 100;
for step in 0..simulation_steps {
// Generate "sensor data"
let sensor_data = solver.generate_test_data(10);
// Run prediction (simulating real-time requirement)
let (prediction, latency) = solver.predict_timed(&sensor_data)?;
total_latency += latency;
max_latency = max_latency.max(latency);
// Simulate real-time constraints
if latency > 1.0 {
println!("⚠️ Step {}: Latency exceeded 1ms ({:.3}ms)", step, latency);
}
if step % 20 == 0 {
println!(" Step {}: {:.3}ms latency", step, latency);
}
// Simulate 10ms control loop
std::thread::sleep(std::time::Duration::from_millis(10));
}
let avg_latency = total_latency / simulation_steps as f64;
println!("✅ Real-time simulation complete:");
println!(" Steps: {}", simulation_steps);
println!(" Average latency: {:.3}ms", avg_latency);
println!(" Maximum latency: {:.3}ms", max_latency);
println!(" Real-time capable: {}", if max_latency < 1.0 { "" } else { "" });
Ok(())
}
}
/// Main entry point for Rust integration example
fn main() -> Result<()> {
println!("🚀 Temporal Neural Solver - Rust Integration Example");
println!("=====================================================");
// Initialize logging
env_logger::init();
// Run all demonstrations
demo::basic_usage()?;
demo::benchmark_demo()?;
demo::onnx_export_demo()?;
demo::realtime_simulation()?;
println!("\n🎉 Rust integration example complete!");
println!("\n💡 Integration Tips:");
println!(" • Use RustTemporalSolver for high-performance applications");
println!(" • Export to ONNX for cross-platform deployment");
println!(" • Monitor latency in production with predict_timed()");
println!(" • Implement proper error handling for production use");
println!(" • Consider async patterns for concurrent inference");
println!("\n📚 Next Steps:");
println!(" • Integrate into your Rust application");
println!(" • Customize for your specific data format");
println!(" • Implement production monitoring and alerting");
println!(" • Consider GPU acceleration for batch processing");
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_solver_creation() {
// Test with default configuration
let config = Config::default_system_b();
let result = RustTemporalSolver {
model: Box::new(SystemB::new(config.model.clone()).unwrap()),
predictor: Predictor::new(
SystemB::new(config.model.clone()).unwrap(),
config.inference.clone()
).unwrap(),
config,
};
// Basic validation
assert!(true); // If we get here, creation succeeded
}
#[test]
fn test_data_generation() {
let config = Config::default_system_b();
let solver = RustTemporalSolver {
model: Box::new(SystemB::new(config.model.clone()).unwrap()),
predictor: Predictor::new(
SystemB::new(config.model.clone()).unwrap(),
config.inference.clone()
).unwrap(),
config,
};
let data = solver.generate_test_data(10);
assert_eq!(data.len(), 40); // 10 timesteps * 4 features
}
#[test]
fn test_benchmark_structure() {
// Test with minimal iterations for fast testing
let config = Config::default_system_b();
let solver = RustTemporalSolver {
model: Box::new(SystemB::new(config.model.clone()).unwrap()),
predictor: Predictor::new(
SystemB::new(config.model.clone()).unwrap(),
config.inference.clone()
).unwrap(),
config,
};
let metrics = solver.benchmark(10).unwrap();
assert!(metrics.num_samples > 0);
assert!(metrics.mean_latency_ms > 0.0);
assert!(metrics.success_rate > 0.0);
}
}