Skip to main content

torsh_tensor/
lib.rs

1//! Tensor implementation for ToRSh with PyTorch-compatible API
2//!
3//! This crate provides a high-level tensor API that wraps scirs2's autograd
4//! functionality with a familiar PyTorch-like interface.
5//!
6//! # Architecture
7//!
8//! The tensor implementation is organized into specialized modules:
9//!
10//! - [`storage`] - Storage management with automatic memory mapping optimization
11//! - [`core_ops`] - Core tensor operations, creation, and gradient management
12//! - [`shape_ops`] - Shape manipulation, views, and dimension operations
13//! - [`data_ops`] - Data access, indexing, and manipulation operations
14//! - [`advanced_ops`] - Advanced operations, reductions, and backend integration
15//! - [`math_ops`] - Mathematical operations and functions
16//! - [`complex_ops`] - Complex number operations and specialized autograd
17//!
18//! # Quick Start
19//!
20//! ```rust
21//! use torsh_tensor::Tensor;
22//! use torsh_core::device::DeviceType;
23//!
24//! // Create a tensor
25//! let data = vec![1.0f32, 2.0, 3.0, 4.0];
26//! let tensor = Tensor::from_data(data, vec![2, 2], DeviceType::Cpu)?;
27//!
28//! // Basic operations
29//! let reshaped = tensor.view(&[4, 1])?;
30//! let sum = tensor.sum()?;
31//! let norm_val = tensor.norm()?.item()?;
32//! let normalized = tensor.div_scalar(norm_val)?;
33//!
34//! // Enable gradients for autograd
35//! let x = tensor.requires_grad_(true);
36//! let y = x.pow(2.0)?;
37//! let loss = y.sum()?;  // Create scalar for backward pass
38//! loss.backward()?;
39//! # Ok::<(), torsh_core::error::TorshError>(())
40//! ```
41//!
42//! # Features
43//!
44//! - **Automatic memory management**: Optimized storage with memory mapping for large tensors
45//! - **Zero-copy views**: Efficient tensor views with shared underlying data
46//! - **PyTorch compatibility**: Familiar API for easy migration from PyTorch
47//! - **Automatic differentiation**: Full gradient computation support
48//! - **Device abstraction**: CPU and GPU device support
49//! - **Complex numbers**: Native complex tensor operations
50//! - **SciRS2 integration**: Optimized backend operations for performance
51
52#![cfg_attr(not(feature = "std"), no_std)]
53
54#[cfg(not(feature = "std"))]
55extern crate alloc;
56
57// Core modules providing the tensor implementation
58pub mod adaptive_auto_tuner;
59pub mod advanced_ops;
60pub mod advanced_simd_ops;
61pub mod algorithmic_optimizations;
62pub mod complex_ops;
63pub mod comprehensive_integration_tests;
64pub mod computation_graph;
65pub mod core_ops;
66pub mod cross_platform_validator;
67pub mod data_ops;
68pub mod expression_optimizer;
69pub mod expression_templates;
70pub mod hardware_accelerators;
71pub mod manipulation;
72pub mod math_ops;
73pub mod memory_optimization;
74pub mod optimization_cli;
75pub mod shape_ops;
76pub mod storage;
77pub mod ultimate_integration_optimizer;
78pub mod ultra_performance_profiler;
79
80// Utility and integration modules
81#[cfg(feature = "async")]
82pub mod async_ops;
83pub mod auto_batching;
84pub mod backend_integration;
85pub mod bfloat16_ops;
86pub mod broadcast;
87pub mod cache_optimization;
88pub mod conv;
89pub mod convenience;
90pub mod creation;
91/// ToRSh-owned thin CUDA backend over oxicuda leaf crates (used by gpu_dispatch).
92#[cfg(feature = "cuda")]
93mod cuda_backend;
94pub mod custom_dtype;
95pub mod custom_ops;
96/// GPU compute dispatch backed by oxicuda's `ComputeBackend` (replaces scirs2-core GPU).
97#[cfg(feature = "gpu")]
98pub mod gpu_dispatch;
99pub mod indexing;
100pub mod lazy_loading;
101// pub mod lazy_ops; // Temporarily disabled due to complex trait bounds - using fluent API instead
102pub mod lockfree_cache;
103pub mod memory_pool;
104#[cfg(feature = "memory-profiling")]
105pub mod memory_profiler;
106pub mod nan_inf_detection;
107#[cfg(feature = "operation-logging")]
108pub mod operation_logging;
109// pub mod ops; // Disabled due to duplicate definitions with core modules (all, any, sum, mean, matmul, cat, etc.)
110pub mod fft;
111pub mod scirs2_backend;
112pub mod scirs2_stats_integration;
113pub mod shape_inference_debugger;
114pub mod simd_ops_f32;
115pub mod sparse;
116pub mod stats;
117pub mod tensor_comprehension;
118pub mod tensor_tracker;
119pub mod tensor_utils;
120pub mod tensor_view; // Zero-copy tensor views (CRITICAL #1)
121pub mod tensor_views;
122pub mod type_conversions;
123
124// TODO: Implement custom data types module
125// #[cfg(feature = "custom-types")]
126// pub mod custom_data_types;
127
128#[cfg(feature = "serialize")]
129pub mod serialize;
130
131// Re-export core types and traits
132use torsh_core::{
133    device::DeviceType,
134    dtype::{FloatElement, TensorElement},
135    error::Result,
136};
137
138// Re-export the main tensor type
139pub use core_ops::{Operation, Tensor};
140
141// Re-export convenience methods
142pub use convenience::{FluentTensor, TensorConvenience, TensorFluentExt};
143
144// Re-export lazy evaluation functionality (temporarily disabled)
145// pub use lazy_ops::{LazyTensor, TensorLazyExt};
146
147// Re-export sparse tensor functionality (COO, CSR, CSC formats)
148pub use sparse::{SparseCSC, SparseCSR, SparseTensor};
149
150// Re-export custom operation functionality
151pub use custom_ops::{
152    global_registry, CustomOperation, CustomOperationRegistry, OperationMetadata, OperationParams,
153    TensorCustomOps,
154};
155
156// Re-export storage types for advanced usage
157pub use storage::{MemoryMappedStorage, TensorStorage};
158
159// Re-export zero-copy view types (CRITICAL #1)
160pub use tensor_view::{TensorView, TensorViewMut};
161
162// Version information
163pub const VERSION: &str = env!("CARGO_PKG_VERSION");
164pub const VERSION_MAJOR: u32 = 0;
165pub const VERSION_MINOR: u32 = 1;
166pub const VERSION_PATCH: u32 = 0;
167
168/// Tensor creation macro similar to PyTorch
169#[macro_export]
170macro_rules! tensor {
171    // 1D array from bracketed values
172    ([$($val:expr),+ $(,)?]) => {
173        $crate::creation::tensor_1d(&[$($val),+])
174    };
175
176    // Multiple values without brackets (at least 2 values to avoid scalar conflict)
177    ($val1:expr, $val2:expr $(, $val:expr)* $(,)?) => {
178        $crate::creation::tensor_1d(&[$val1, $val2 $(, $val)*])
179    };
180
181    // Single value (scalar)
182    ($val:expr) => {
183        $crate::creation::tensor_scalar($val)
184    };
185}
186
187/// 2D tensor creation macro
188#[macro_export]
189macro_rules! tensor_2d {
190    ([$($row:expr),+ $(,)?]) => {{
191        let rows: Vec<Vec<_>> = vec![$($row.to_vec()),+];
192        let row_refs: Vec<&[_]> = rows.iter().map(|row| row.as_slice()).collect();
193        $crate::creation::tensor_2d(&row_refs)
194    }};
195}
196
197// Display implementation for Tensor
198impl<T: TensorElement> std::fmt::Debug for Tensor<T> {
199    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
200        write!(
201            f,
202            "Tensor(shape={:?}, dtype={}, device={})",
203            self.shape().dims(),
204            self.dtype(),
205            self.device
206        )
207    }
208}
209
210// Additional utility implementations
211impl<T: TensorElement> Tensor<T> {
212    /// Get the reference count of the underlying storage Arc (for testing CoW behavior)
213    #[cfg(test)]
214    pub fn data_ref_count(&self) -> usize {
215        use std::sync::Arc;
216        match &self.storage {
217            TensorStorage::InMemory(data) => Arc::strong_count(data),
218            TensorStorage::MemoryMapped(storage) => Arc::strong_count(storage),
219            #[cfg(feature = "simd")]
220            TensorStorage::Aligned(data) => Arc::strong_count(data),
221            #[cfg(feature = "simd")]
222            TensorStorage::SimdOptimized(storage) => Arc::strong_count(storage),
223        }
224    }
225
226    /// Create from vec with shape (convenience method)
227    pub fn from_vec(data: Vec<T>, shape: &[usize]) -> Result<Self>
228    where
229        T: Copy,
230    {
231        Self::from_data(data, shape.to_vec(), DeviceType::Cpu)
232    }
233}
234
235// TODO: Conditional AutogradTensor trait implementation - torsh-autograd not yet available
236// #[cfg(feature = "autograd")]
237// impl<T: TensorElement> torsh_autograd::AutogradTensor<T> for Tensor<T> {
238//     fn shape(&self) -> Shape {
239//         self.shape()
240//     }
241//
242//     fn requires_grad(&self) -> bool {
243//         self.requires_grad()
244//     }
245//
246//     fn data(&self) -> Box<dyn std::ops::Deref<Target = [T]> + '_> {
247//         // Return a boxed vector that can be dereferenced as a slice
248//         Box::new(self.to_vec().unwrap_or_default())
249//     }
250//
251//     fn clone_tensor(&self) -> Box<dyn torsh_autograd::AutogradTensor<T>> {
252//         Box::new(self.clone())
253//     }
254//
255//     fn to_vec(&self) -> Vec<T>
256//     where
257//         T: Copy,
258//     {
259//         self.to_vec().unwrap_or_default()
260//     }
261//
262//     fn device(&self) -> &dyn torsh_core::Device {
263//         match &self.device {
264//             DeviceType::Cpu => {
265//                 static CPU_DEVICE: torsh_core::device::CpuDevice =
266//                     torsh_core::device::CpuDevice::new();
267//                 &CPU_DEVICE
268//             }
269//             DeviceType::Cuda(_) => {
270//                 static CPU_DEVICE: torsh_core::device::CpuDevice =
271//                     torsh_core::device::CpuDevice::new();
272//                 &CPU_DEVICE // TODO: Return proper CUDA device
273//             }
274//             _ => {
275//                 static CPU_DEVICE: torsh_core::device::CpuDevice =
276//                     torsh_core::device::CpuDevice::new();
277//                 &CPU_DEVICE
278//             }
279//         }
280//     }
281//
282//     fn ones_like(&self) -> Box<dyn torsh_autograd::AutogradTensor<T>>
283//     where
284//         T: Copy,
285//     {
286//         Box::new(self.ones_like().unwrap_or_else(|_| self.clone()))
287//     }
288//
289//     fn zeros_like(&self) -> Box<dyn torsh_autograd::AutogradTensor<T>>
290//     where
291//         T: Copy,
292//     {
293//         Box::new(self.zeros_like().unwrap_or_else(|_| self.clone()))
294//     }
295// }
296
297// Re-export commonly used functions and types for convenience
298pub mod prelude {
299    pub use crate::advanced_simd_ops::{
300        AdvancedSimdOps, ReductionType, SimdConfig, SimdPerformanceInfo,
301    };
302    pub use crate::algorithmic_optimizations::{
303        AlgorithmConfig, AlgorithmPerformanceStats, AlgorithmicOptimizer, SchedulingStrategy,
304    };
305    pub use crate::comprehensive_integration_tests::{
306        run_comprehensive_integration_tests, ComprehensiveIntegrationTestSuite,
307        ComprehensiveTestReport, IntegrationAnalysis, IntegrationTestConfig, PerformanceAnalysis,
308        StabilityAnalysis, TestCategory,
309    };
310    pub use crate::core_ops::Operation;
311    pub use crate::creation::{eye, ones, rand, randn, zeros};
312    pub use crate::cross_platform_validator::{
313        CpuArchitecture, CrossPlatformReport, CrossPlatformValidator, GpuVendor,
314        HardwareDetectionReport, HardwareDetector, OptimizationConfig, OptimizationReport,
315        Platform, PlatformOptimizer, ValidationConfig, ValidationFramework, ValidationReport,
316    };
317    pub use crate::expression_optimizer::{
318        ExpressionGraph, ExpressionNode, ExpressionOptimizer, NodeId, OperationType,
319        OptimizationStats, OptimizationStrategy, OptimizerConfig, TensorExpressionOps,
320    };
321    pub use crate::hardware_accelerators::{
322        AccelerationWorkload, ComplexityLevel, CpuAccelerationMetrics, CpuAcceleratorEngine,
323        GpuAccelerationMetrics, GpuAcceleratorEngine, HardwareAcceleratorReport,
324        HardwareAcceleratorSystem, MemoryAccelerationMetrics, MemoryAcceleratorEngine,
325        NetworkAccelerationMetrics, OptimizationCoordinator, SpecializedAcceleratorEngine,
326        WorkloadType,
327    };
328    pub use crate::memory_optimization::{
329        AdvancedMemoryPool, AggregateMemoryStats, DefragmentationReport, GlobalMemoryOptimizer,
330        MemoryConfig, MemoryStats,
331    };
332    pub use crate::optimization_cli::{
333        run_cli_command, run_optimization_cli, CLICommand, CLIConfig, OptimizationCLI,
334        OptimizationLevel, OptimizationType,
335    };
336    pub use crate::ultimate_integration_optimizer::{
337        CrossLayerSynergyGains, EfficiencyImprovements, EnergyEfficiencyImprovements,
338        GlobalPerformanceCache, IntelligentLearningSystem, LayerSpecificImprovements,
339        OptimizationComplexity, OptimizationStatus, ScalabilityImprovements,
340        SystemOptimizationCoordinator, UltimateIntegrationOptimizer, UltimateOptimizationResult,
341    };
342    pub use crate::{Tensor, TensorConvenience, TensorStorage};
343    pub use torsh_core::{
344        device::DeviceType,
345        dtype::{DType, FloatElement, TensorElement},
346        error::{Result, TorshError},
347        shape::Shape,
348    };
349}
350
351#[cfg(test)]
352mod integration_tests {
353    use super::*;
354    use torsh_core::device::DeviceType;
355    use torsh_core::dtype::DType;
356
357    #[test]
358    fn test_tensor_creation_and_basic_ops() {
359        let data = vec![1.0f32, 2.0, 3.0, 4.0];
360        let tensor = Tensor::from_data(data, vec![2, 2], DeviceType::Cpu)
361            .expect("tensor creation should succeed");
362
363        assert_eq!(tensor.shape().dims(), &[2, 2]);
364        assert_eq!(tensor.numel(), 4);
365        assert_eq!(tensor.dtype(), DType::F32);
366    }
367
368    #[test]
369    fn test_tensor_reshape_and_view() {
370        let data = vec![1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0];
371        let tensor = Tensor::from_data(data, vec![2, 3], DeviceType::Cpu)
372            .expect("tensor creation should succeed");
373
374        let reshaped = tensor.view(&[3, 2]).expect("view should succeed");
375        assert_eq!(reshaped.shape().dims(), &[3, 2]);
376
377        let slice = tensor
378            .slice_tensor(0, 0, 1)
379            .expect("slice_tensor should succeed");
380        assert_eq!(slice.shape().dims(), &[1, 3]);
381    }
382
383    #[test]
384    fn test_tensor_math_operations() {
385        let a = Tensor::from_data(vec![1.0f32, 2.0, 3.0], vec![3], DeviceType::Cpu)
386            .expect("tensor creation should succeed");
387        let b = Tensor::from_data(vec![4.0f32, 5.0, 6.0], vec![3], DeviceType::Cpu)
388            .expect("tensor creation should succeed");
389
390        let sum = a.add(&b).expect("addition should succeed");
391        assert_eq!(
392            sum.data().expect("data retrieval should succeed"),
393            vec![5.0, 7.0, 9.0]
394        );
395
396        let product = a.mul(&b).expect("multiplication should succeed");
397        assert_eq!(
398            product.data().expect("data retrieval should succeed"),
399            vec![4.0, 10.0, 18.0]
400        );
401    }
402
403    #[test]
404    fn test_tensor_advanced_operations() {
405        let data = vec![1.0f32, 4.0, 9.0, 16.0];
406        let tensor = Tensor::from_data(data, vec![4], DeviceType::Cpu)
407            .expect("tensor creation should succeed");
408
409        let sqrt_result = tensor.sqrt().expect("sqrt should succeed");
410        assert_eq!(
411            sqrt_result.data().expect("data retrieval should succeed"),
412            vec![1.0, 2.0, 3.0, 4.0]
413        );
414
415        let norm = tensor.norm().expect("norm should succeed");
416        assert!(norm.item().expect("item extraction should succeed") > 0.0);
417    }
418
419    #[test]
420    fn test_tensor_data_operations() {
421        let mut tensor =
422            Tensor::<f32>::zeros(&[2, 3], DeviceType::Cpu).expect("zeros creation should succeed");
423
424        tensor.fill_(5.0).expect("fill should succeed");
425        assert_eq!(
426            tensor.get_item(&[0, 0]).expect("get_item should succeed"),
427            5.0
428        );
429
430        let indices = Tensor::from_data(vec![0i64, 2], vec![2], DeviceType::Cpu)
431            .expect("tensor creation should succeed");
432        let _src = Tensor::from_data(vec![10.0f32, 20.0], vec![2], DeviceType::Cpu)
433            .expect("tensor creation should succeed");
434
435        let data_1d = vec![1.0f32, 2.0, 3.0, 4.0, 5.0];
436        let tensor_1d = Tensor::from_data(data_1d, vec![5], DeviceType::Cpu)
437            .expect("tensor creation should succeed");
438        let gathered = tensor_1d
439            .gather(0, &indices)
440            .expect("gather should succeed");
441        assert_eq!(
442            gathered.data().expect("data retrieval should succeed"),
443            vec![1.0, 3.0]
444        );
445    }
446
447    #[test]
448    fn test_tensor_storage_optimization() {
449        // Small tensor should use in-memory storage
450        let small =
451            Tensor::<f32>::zeros(&[10], DeviceType::Cpu).expect("zeros creation should succeed");
452        assert_eq!(small.storage_type(), "in_memory");
453
454        // Test copy-on-write behavior
455        let tensor1 =
456            Tensor::<f32>::ones(&[5], DeviceType::Cpu).expect("ones creation should succeed");
457        let tensor2 = tensor1.clone();
458        assert!(tensor1.shares_storage(&tensor2));
459    }
460
461    #[test]
462    fn test_gradient_operations() {
463        let tensor = Tensor::<f32>::ones(&[2, 2], DeviceType::Cpu)
464            .expect("ones creation should succeed")
465            .requires_grad_(true);
466
467        assert!(tensor.requires_grad());
468        assert!(!tensor.has_grad());
469
470        let detached = tensor.detach();
471        assert!(!detached.requires_grad());
472    }
473}