Skip to main content

torsh_nn/
functional.rs

1//! Functional interface for neural network operations
2//! Enhanced with SciRS2-Neural integration for optimized performance
3//!
4//! This module provides a comprehensive, functional API for neural network operations
5//! with modular architecture, standardized error handling, parameter validation, and performance optimizations.
6//!
7//! # Modular Architecture
8//!
9//! The functional API is organized into specialized modules for improved maintainability:
10//!
11//! - **core**: Core infrastructure, configuration, validation, and utilities
12//! - **activation**: Activation functions (ReLU, Sigmoid, Tanh, GELU, etc.)
13//! - **conv**: Convolution operations (1D, 2D, 3D) with comprehensive parameter support
14//! - **pooling**: Pooling operations (max, average, adaptive, global)
15//! - **linear**: Linear transformations, attention mechanisms, and embedding operations
16//! - **loss**: Basic loss functions (cross entropy, MSE, L1, KL divergence, etc.)
17//! - **loss_advanced**: Advanced loss framework with composable building blocks
18//! - **norm**: Normalization operations (batch norm, layer norm, group norm, etc.)
19//!
20//! All components maintain full backward compatibility through comprehensive re-exports.
21
22// Modular architecture imports
23pub mod activation;
24pub mod conv;
25pub mod core;
26pub mod linear;
27pub mod loss;
28pub mod loss_advanced;
29pub mod norm;
30pub mod pooling;
31
32// Re-export core functionality for convenience
33pub use core::*;
34
35// =============================================================================
36// ACTIVATION FUNCTIONS - COMPLETE BACKWARD COMPATIBILITY
37// =============================================================================
38
39// Enhanced activation functions with SciRS2 integration
40pub use activation::{
41    dropout, elu, gelu, leaky_relu, log_softmax, mish, relu, relu_inplace, selu, sigmoid, softmax,
42    swish, tanh,
43};
44
45// Activation function structs for trait-based usage
46pub use activation::{
47    LeakyReLU, LogSoftmax, Mish, ReLU, Sigmoid, Softmax, Swish, Tanh, ELU, GELU, SELU,
48};
49
50// Configured activation functions with validation
51pub use activation::configured::{
52    gelu_configured, mish_configured, relu_configured, sigmoid_configured, softmax_configured,
53    swish_configured, tanh_configured,
54};
55
56// =============================================================================
57// CONVOLUTION OPERATIONS - COMPLETE BACKWARD COMPATIBILITY
58// =============================================================================
59
60// Standard convolution operations
61pub use conv::{conv1d, conv2d, conv3d, conv_transpose1d, conv_transpose2d, conv_transpose3d};
62
63// Utility functions
64pub use conv::{conv_output_size, conv_transpose_output_size, validate_conv_params};
65
66// =============================================================================
67// POOLING OPERATIONS - COMPLETE BACKWARD COMPATIBILITY
68// =============================================================================
69
70// Max pooling operations
71pub use pooling::{
72    adaptive_max_pool1d, adaptive_max_pool2d, adaptive_max_pool3d, global_max_pool1d,
73    global_max_pool2d, global_max_pool3d, max_pool1d, max_pool2d, max_pool3d,
74};
75
76// Average pooling operations
77pub use pooling::{
78    adaptive_avg_pool1d, adaptive_avg_pool2d, adaptive_avg_pool3d, avg_pool1d, avg_pool2d,
79    avg_pool3d, global_avg_pool1d, global_avg_pool2d, global_avg_pool3d,
80};
81
82// Padding operations
83pub use pooling::{
84    pad, reflection_pad1d, reflection_pad2d, replication_pad1d, replication_pad2d, zero_pad2d,
85};
86
87// Utility functions
88pub use pooling::{adaptive_pool_params, pool_output_size};
89
90// =============================================================================
91// LINEAR AND ATTENTION OPERATIONS - COMPLETE BACKWARD COMPATIBILITY
92// =============================================================================
93
94// Linear transformations
95pub use linear::{bilinear, linear};
96
97// Embedding operations
98pub use linear::{embedding, embedding_bag, one_hot};
99
100// Attention mechanisms
101pub use linear::{
102    grouped_query_attention, multi_head_attention, multi_query_attention,
103    scaled_dot_product_attention,
104};
105
106// Positional encoding
107pub use linear::{
108    learnable_positional_encoding, rotary_positional_encoding, sinusoidal_positional_encoding,
109};
110
111// Normalization in attention
112pub use linear::{post_norm_layer_norm, pre_norm_layer_norm, rms_norm};
113
114// Gating mechanisms
115pub use linear::{geglu, glu, swiglu};
116
117// Utility functions
118pub use linear::{apply_attention_mask, create_causal_mask, create_padding_mask};
119
120// =============================================================================
121// LOSS FUNCTIONS - COMPLETE BACKWARD COMPATIBILITY
122// =============================================================================
123
124// Classification losses
125pub use loss::{
126    binary_cross_entropy, binary_cross_entropy_with_logits, cross_entropy, focal_loss,
127    multi_margin_loss, multilabel_margin_loss, nll_loss,
128};
129
130// Regression losses
131pub use loss::{huber_loss, l1_loss, mse_loss, smooth_l1_loss};
132
133// Probabilistic losses
134pub use loss::kl_div;
135
136// Ranking and similarity losses
137pub use loss::{contrastive_loss, cosine_embedding_loss, triplet_margin_loss};
138
139// Modern loss functions
140pub use loss::{center_loss, dice_loss, infonce_loss, tversky_loss, wing_loss};
141
142// =============================================================================
143// ADVANCED LOSS FRAMEWORK - COMPLETE BACKWARD COMPATIBILITY
144// =============================================================================
145
146// Advanced loss framework
147pub use loss_advanced::{CustomLoss, LossBuilder, LossFactory, Reduction};
148
149// Advanced loss implementations
150pub use loss_advanced::{
151    AdaptiveLoss, CombinedLoss, DiceLoss, IoULoss, SmoothL1Loss, WeightedLoss,
152};
153
154// Pre-built loss function structs
155pub use loss_advanced::{
156    BinaryCrossEntropy, CategoricalCrossEntropy, CosineEmbeddingLoss, FocalLoss, HingeLoss,
157    HuberLoss, KLDivLoss, L1Loss, MSELoss, NLLLoss, TripletMarginLoss,
158};
159
160// Validation utilities
161pub use loss_advanced::validation as loss_validation;
162
163// =============================================================================
164// NORMALIZATION OPERATIONS - COMPLETE BACKWARD COMPATIBILITY
165// =============================================================================
166
167// Batch normalization
168pub use norm::{
169    batch_norm, batch_norm_1d, batch_norm_2d, batch_norm_2d_with_config, batch_norm_3d,
170};
171
172// Layer normalization
173pub use norm::{layer_norm, layer_norm_configured, layer_norm_enhanced};
174
175// Other normalization methods
176pub use norm::{
177    group_norm, instance_norm, local_response_norm, rms_norm as rms_norm_standalone, spectral_norm,
178    weight_norm,
179};
180
181// Configured normalization functions
182pub use norm::configured::batch_norm_configured;
183
184// Utility functions
185pub use norm::{create_affine_params, get_norm_features, validate_norm_params};
186
187// =============================================================================
188// CONVENIENT API MODULES - COMPLETE BACKWARD COMPATIBILITY
189// =============================================================================
190
191/// Convenient activation functions with standardized API
192pub mod activations {
193    pub use super::activation::configured::*;
194    // Re-export base functions for convenience
195    pub use super::activation::{gelu, mish, relu, sigmoid, softmax, swish, tanh};
196}
197
198/// Convenient loss functions with standardized API
199pub mod losses {
200    pub use super::loss::*;
201
202    /// MSE loss with configuration
203    pub fn mse_loss_configured(
204        input: &crate::Tensor,
205        target: &crate::Tensor,
206        reduction: &str,
207        config: &super::FunctionalConfig,
208    ) -> super::FuncResult<crate::Tensor> {
209        crate::validate_inputs!(
210            config,
211            super::validation::validate_not_empty(input, "input"),
212            super::validation::validate_not_empty(target, "target"),
213            super::validation::validate_compatible_shapes(input, target, "MSE loss")
214        );
215        crate::func_error!(super::mse_loss(input, target, reduction), "MSE loss")
216    }
217
218    /// L1 loss with configuration
219    pub fn l1_loss_configured(
220        input: &crate::Tensor,
221        target: &crate::Tensor,
222        reduction: &str,
223        config: &super::FunctionalConfig,
224    ) -> super::FuncResult<crate::Tensor> {
225        crate::validate_inputs!(
226            config,
227            super::validation::validate_not_empty(input, "input"),
228            super::validation::validate_not_empty(target, "target"),
229            super::validation::validate_compatible_shapes(input, target, "L1 loss")
230        );
231        crate::func_error!(super::l1_loss(input, target, reduction), "L1 loss")
232    }
233
234    /// Cross entropy loss with configuration
235    pub fn cross_entropy_configured(
236        input: &crate::Tensor,
237        target: &crate::Tensor<i64>,
238        weight: Option<&crate::Tensor>,
239        ignore_index: Option<i64>,
240        reduction: &str,
241        config: &super::FunctionalConfig,
242    ) -> super::FuncResult<crate::Tensor> {
243        crate::validate_inputs!(
244            config,
245            super::validation::validate_not_empty(input, "input"),
246            super::validation::validate_not_empty(target, "target"),
247            super::validation::validate_min_ndim(input, 2, "input")
248        );
249        crate::func_error!(
250            super::cross_entropy(input, target, weight, reduction, ignore_index),
251            "Cross entropy loss"
252        )
253    }
254}
255
256/// Convenient normalization functions with standardized API
257pub mod normalization {
258    pub use super::norm::configured::*;
259    // Re-export base functions for convenience
260    pub use super::norm::{batch_norm_2d, layer_norm_enhanced};
261}
262
263// =============================================================================
264// FUNCTIONAL API PRELUDE
265// =============================================================================
266
267/// Prelude module for convenient functional API imports
268pub mod prelude {
269    pub use super::{
270        activations, default_config, losses, normalization, numerics, optimized, performance, safe,
271        validation, Activation, ActivationConfig, CustomLoss, FunctionalBuilder, FunctionalConfig,
272        LossBuilder, MemoryOptLevel, Reduction,
273    };
274}
275
276// =============================================================================
277// UTILITY RE-EXPORTS FOR BACKWARD COMPATIBILITY
278// =============================================================================
279
280// Import types needed for compatibility
281use torsh_core::error::Result;
282use torsh_tensor::Tensor;
283
284/// Extension trait to add tensor casting for compatibility
285#[allow(dead_code)]
286trait TensorCast {
287    fn cast_i64(&self) -> Result<Tensor<i64>>;
288}
289
290#[allow(dead_code)]
291impl TensorCast for Tensor {
292    fn cast_i64(&self) -> Result<Tensor<i64>> {
293        // Simplified casting - in practice would need proper tensor type conversion
294        let data = self.to_vec()?;
295        let i64_data: Vec<i64> = data.into_iter().map(|x| x as i64).collect();
296        Ok(Tensor::from_data(
297            i64_data,
298            self.shape().dims().to_vec(),
299            self.device(),
300        )?)
301    }
302}
303
304/// Sparse Matrix placeholder for compatibility
305pub struct SparseMatrix;
306
307impl SparseMatrix {
308    pub fn new() -> Self {
309        Self
310    }
311}
312
313impl Default for SparseMatrix {
314    fn default() -> Self {
315        Self::new()
316    }
317}
318
319// =============================================================================
320// ENHANCED OPERATIONS WITH SCIRS2 INTEGRATION
321// =============================================================================
322
323/// Enhanced batch normalization with standardized API and SciRS2 numerical stability
324/// Re-exported from norm module for backward compatibility (covered by group import above)
325
326/// Enhanced layer normalization with SciRS2 numerical stability
327/// Re-exported from norm module for backward compatibility (covered by group import above)
328
329// =============================================================================
330// TESTS AND EXAMPLES
331// =============================================================================
332
333#[cfg(test)]
334mod tests {
335    use super::*;
336
337    #[test]
338    fn test_modular_functional_system() {
339        // Test that all modules are accessible and working
340
341        // Test activation functions
342        let input = torsh_tensor::creation::randn::<f32>(&[2, 4]).unwrap();
343        let _relu_result = relu(&input).unwrap();
344        let _sigmoid_result = sigmoid(&input).unwrap();
345        let _tanh_result = tanh(&input).unwrap();
346
347        // Test configuration-based functions
348        let config = FunctionalConfig::default();
349        let _configured_relu = activations::relu_configured(&input, &config).unwrap();
350
351        // Test builder patterns
352        let _optimized_config = optimized().build();
353        let _safe_config = safe().build();
354    }
355
356    #[test]
357    fn test_backward_compatibility() {
358        // Ensure that the modular system maintains full backward compatibility
359        // All original function names and APIs should work exactly as before
360
361        let input = torsh_tensor::creation::randn::<f32>(&[4, 3, 32, 32]).unwrap();
362        let weight = torsh_tensor::creation::ones(&[3]).unwrap();
363        let bias = torsh_tensor::creation::zeros(&[3]).unwrap();
364
365        // Test batch normalization
366        let _batch_norm_result = batch_norm_2d(
367            &input,
368            Some(&weight),
369            Some(&bias),
370            None,
371            None,
372            true,
373            0.1,
374            1e-5,
375        )
376        .unwrap();
377
378        // Test original activation functions still work
379        let activation_input = torsh_tensor::creation::randn::<f32>(&[2, 4]).unwrap();
380        let _relu_result = relu(&activation_input).unwrap();
381        let _gelu_result = gelu(&activation_input).unwrap();
382        let _swish_result = swish(&activation_input).unwrap();
383    }
384
385    #[test]
386    fn test_modular_structure_integrity() {
387        // Test that all modules are properly accessible
388
389        // Test core functionality
390        let config = FunctionalConfig::default();
391        assert_eq!(config.validate_inputs, true);
392        assert_eq!(config.eps, 1e-8);
393
394        // Test that builder pattern works
395        let custom_config = FunctionalBuilder::new().eps(1e-6).inplace(true).build();
396        assert_eq!(custom_config.eps, 1e-6);
397        assert_eq!(custom_config.inplace, true);
398
399        // Test that prelude imports work
400        let _default_conf = prelude::default_config();
401    }
402
403    #[test]
404    fn test_loss_framework() {
405        // Test the advanced loss framework
406        let predictions = torsh_tensor::creation::randn::<f32>(&[4, 10]).unwrap();
407        let targets = torsh_tensor::creation::randn::<f32>(&[4, 10]).unwrap();
408
409        // Test MSE loss
410        let mse = MSELoss::new(Reduction::Mean);
411        let _loss_result = mse.compute_loss(&predictions, &targets).unwrap();
412
413        // Test builder pattern
414        let _smooth_l1 = LossBuilder::new()
415            .with_reduction(Reduction::Sum)
416            .smooth_l1(1.0);
417    }
418}
419
420/// Example usage demonstrating the modular functional API
421#[cfg(test)]
422mod examples {
423    use super::*;
424
425    #[test]
426    fn example_basic_usage() {
427        // Create some sample data
428        let input = torsh_tensor::creation::randn::<f32>(&[4, 3, 32, 32]).unwrap();
429        let target = torsh_tensor::creation::randn::<f32>(&[4, 10]).unwrap();
430
431        // Use activation functions
432        let activated = relu(&input).unwrap();
433        let _softmax_result = softmax(&activated, Some(-1)).unwrap();
434
435        // Test batch normalization
436        let weight = torsh_tensor::creation::ones(&[3]).unwrap();
437        let bias = torsh_tensor::creation::zeros(&[3]).unwrap();
438        let _normalized = batch_norm_2d(
439            &input,
440            Some(&weight),
441            Some(&bias),
442            None,
443            None,
444            true,
445            0.1,
446            1e-5,
447        )
448        .unwrap();
449
450        // Use loss functions
451        let predictions = torsh_tensor::creation::randn::<f32>(&[4, 10]).unwrap();
452        let _mse_loss = mse_loss(&predictions, &target, "mean").unwrap();
453    }
454
455    #[test]
456    fn example_configured_usage() {
457        // Create configuration
458        let config = FunctionalBuilder::new()
459            .validate(true)
460            .eps(1e-6)
461            .memory_opt(MemoryOptLevel::Maximum)
462            .build();
463
464        let input = torsh_tensor::creation::randn::<f32>(&[4, 8]).unwrap();
465
466        // Use configured functions
467        let _relu_result = activations::relu_configured(&input, &config).unwrap();
468        let _sigmoid_result = activations::sigmoid_configured(&input, &config).unwrap();
469    }
470
471    #[test]
472    fn example_advanced_loss_usage() {
473        let predictions = torsh_tensor::creation::randn::<f32>(&[4, 10]).unwrap();
474        let targets = torsh_tensor::creation::randn::<f32>(&[4, 10]).unwrap();
475
476        // Use advanced loss framework
477        let dice_loss = LossBuilder::new()
478            .with_reduction(Reduction::Mean)
479            .dice(1e-6);
480
481        let _loss_result = dice_loss.compute_loss(&predictions, &targets).unwrap();
482
483        // Combine multiple losses
484        let mse = Box::new(MSELoss::new(Reduction::None));
485        let l1 = Box::new(L1Loss::new(Reduction::None));
486
487        let combined = LossBuilder::new()
488            .with_reduction(Reduction::Mean)
489            .combined(vec![mse, l1], vec![0.7, 0.3]);
490
491        let _combined_loss = combined.compute_loss(&predictions, &targets).unwrap();
492    }
493}