168 lines
4.6 KiB
Rust
168 lines
4.6 KiB
Rust
//! Physics-Informed Neural Network Benchmark Backend
|
|
//!
|
|
//! This crate provides a simple, pure-Rust implementation of PINNs for benchmarking
|
|
//! standard PDE problems. It includes:
|
|
//!
|
|
//! - Simple MLP network with numerical differentiation
|
|
//! - AdamW optimizer for training
|
|
//! - Standard PDE problems (Heat1D, Burgers1D, Poisson2D)
|
|
//! - Benchmark utilities for accuracy and performance measurement
|
|
//!
|
|
//! # Example
|
|
//!
|
|
//! ```rust
|
|
//! use rtx_pinn_benchmark::{
|
|
//! error::Result,
|
|
//! network::MLP,
|
|
//! problems::{Heat1D, Problem},
|
|
//! training::AdamW,
|
|
//! };
|
|
//!
|
|
//! # fn main() -> Result<()> {
|
|
//! // Create a problem
|
|
//! let problem = Heat1D::new(0.01, 1.0)?;
|
|
//!
|
|
//! // Create a network
|
|
//! let mut network = MLP::new(2, vec![32, 32], 1)?;
|
|
//! network.initialize_xavier();
|
|
//!
|
|
//! // Generate training points
|
|
//! let collocation_points = problem.collocation_points(1000);
|
|
//! let boundary_points = problem.boundary_points(100);
|
|
//!
|
|
//! # Ok(())
|
|
//! # }
|
|
//! ```
|
|
|
|
pub mod benchmark;
|
|
pub mod error;
|
|
pub mod network;
|
|
pub mod problems;
|
|
pub mod training;
|
|
|
|
// Re-export commonly used types
|
|
pub use error::{PINNError, Result};
|
|
pub use network::MLP;
|
|
pub use problems::{Burgers1D, Heat1D, Poisson2D, Problem};
|
|
pub use training::{mse_loss, AdamW, TrainingConfig};
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_library_basic_workflow() {
|
|
// Create a problem
|
|
let problem = Heat1D::new(0.01, 1.0);
|
|
assert!(problem.is_ok());
|
|
|
|
// Create a network
|
|
let network = MLP::new(2, vec![10], 1);
|
|
assert!(network.is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn test_library_end_to_end() {
|
|
// Create problem
|
|
let problem = Heat1D::new(0.01, 1.0).unwrap();
|
|
|
|
// Create network
|
|
let mut network = MLP::new(2, vec![5], 1).unwrap();
|
|
network.initialize_xavier();
|
|
|
|
// Generate points
|
|
let collocation_points = problem.collocation_points(10);
|
|
let boundary_points = problem.boundary_points(10);
|
|
|
|
assert_eq!(collocation_points.len(), 10);
|
|
assert!(!boundary_points.is_empty());
|
|
|
|
// Forward pass through network
|
|
for point in &collocation_points {
|
|
let output = network.forward(point);
|
|
assert!(output.is_ok());
|
|
let output = output.unwrap();
|
|
assert_eq!(output.len(), 1);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_library_training_setup() {
|
|
// Create network
|
|
let mut network = MLP::new(2, vec![5, 5], 1).unwrap();
|
|
network.initialize_xavier();
|
|
|
|
// Create optimizer
|
|
let weight_shapes: Vec<Vec<Vec<f64>>> = vec![
|
|
vec![vec![0.0; 2]; 5],
|
|
vec![vec![0.0; 5]; 5],
|
|
vec![vec![0.0; 5]; 1],
|
|
];
|
|
let bias_shapes: Vec<Vec<f64>> = vec![vec![0.0; 5], vec![0.0; 5], vec![0.0; 1]];
|
|
|
|
let optimizer = AdamW::new(0.001, 0.9, 0.999, 0.01, &weight_shapes, &bias_shapes);
|
|
assert!(optimizer.is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn test_library_problem_types() {
|
|
let heat = Heat1D::new(0.01, 1.0);
|
|
assert!(heat.is_ok());
|
|
|
|
let burgers = Burgers1D::new(0.01, 1.0);
|
|
assert!(burgers.is_ok());
|
|
|
|
let poisson = Poisson2D::new(std::f64::consts::PI);
|
|
assert!(poisson.is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn test_library_analytical_solutions() {
|
|
let heat = Heat1D::new(0.01, 1.0).unwrap();
|
|
let points = vec![vec![0.5, 0.0]];
|
|
|
|
let solution = heat.analytical_solution(&points);
|
|
assert!(solution.is_some());
|
|
|
|
let poisson = Poisson2D::new(std::f64::consts::PI).unwrap();
|
|
let points = vec![vec![0.5, 0.5]];
|
|
|
|
let solution = poisson.analytical_solution(&points);
|
|
assert!(solution.is_some());
|
|
}
|
|
|
|
#[test]
|
|
fn test_library_mse_loss() {
|
|
let predictions = vec![1.0, 2.0, 3.0];
|
|
let targets = vec![1.1, 2.1, 2.9];
|
|
|
|
let loss = mse_loss(&predictions, &targets);
|
|
assert!(loss.is_ok());
|
|
assert!(loss.unwrap() > 0.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_library_benchmark_config() {
|
|
use benchmark::BenchmarkConfig;
|
|
use pinn_benchmark_shared::ProblemType;
|
|
|
|
let config = BenchmarkConfig::new(ProblemType::Heat1D, vec![32, 32], 0.001, 100, 1000, 100);
|
|
assert!(config.is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn test_library_compute_accuracy() {
|
|
use benchmark::compute_accuracy;
|
|
|
|
let predictions = vec![1.0, 2.0, 3.0];
|
|
let reference = vec![1.0, 2.0, 3.0];
|
|
|
|
let result = compute_accuracy(&predictions, &reference);
|
|
assert!(result.is_ok());
|
|
|
|
let (l2_error, linf_error) = result.unwrap();
|
|
assert!(l2_error < 1e-10);
|
|
assert!(linf_error < 1e-10);
|
|
}
|
|
}
|