245 lines
11 KiB
Markdown
245 lines
11 KiB
Markdown
# RustyTorch++ Preprocessing: Memory-Mapped Files and Distributed Data Loading
|
|
|
|
## Overview
|
|
|
|
This implementation enhances the rtx-preprocessing crate with advanced data loading capabilities following strict Test-Driven Development (TDD) methodology. The new features provide efficient memory-mapped file access and distributed data sharding with fault tolerance, designed to integrate seamlessly with existing preprocessing infrastructure.
|
|
|
|
## Features Implemented
|
|
|
|
### 1. Memory-Mapped File Loading (`memory_mapped.rs`)
|
|
|
|
**Key Features:**
|
|
- **Efficient Large Dataset Loading**: Uses memory-mapped I/O for handling large files without loading everything into RAM
|
|
- **Lazy Loading with Page Faults**: Only loads data pages when accessed, optimizing memory usage
|
|
- **Shared Memory Segments**: Enables multiple processes to access the same memory-mapped data efficiently
|
|
- **Advanced Prefetching Strategies**:
|
|
- Sequential prefetching with configurable window sizes
|
|
- Random access optimization
|
|
- Adaptive prefetching based on access patterns
|
|
- **Performance Statistics**: Comprehensive metrics including cache hits/misses, page loads, and access patterns
|
|
|
|
**Implementation Highlights:**
|
|
- Thread-safe design with `parking_lot::RwLock` for concurrent access
|
|
- Global shared memory registry using `dashmap` for cross-process coordination
|
|
- Configurable page sizes and prefetching strategies
|
|
- Automatic cleanup and reference counting for shared segments
|
|
|
|
### 2. Distributed Data Sharding (`distributed.rs`)
|
|
|
|
**Key Features:**
|
|
- **Multiple Sharding Strategies**:
|
|
- Round-robin distribution for balanced file assignment
|
|
- Hash-based distribution for deterministic placement
|
|
- Size-aware distribution to balance data sizes across shards
|
|
- **Dynamic Rebalancing**:
|
|
- Performance-based rebalancing with configurable thresholds
|
|
- Load-aware rebalancing targeting specific performance metrics
|
|
- **Fault Tolerance**:
|
|
- Health checking for worker nodes
|
|
- Automatic shard reassignment on worker failure
|
|
- Worker recovery handling with redistribution
|
|
- **Performance Monitoring**: Real-time metrics collection and worker performance tracking
|
|
|
|
**Implementation Highlights:**
|
|
- Comprehensive worker lifecycle management
|
|
- Configurable fault tolerance policies
|
|
- Cross-platform design with async-ready architecture
|
|
- Statistical analysis of load distribution and performance
|
|
|
|
### 3. Integration Layer (`integration.rs`)
|
|
|
|
**Key Features:**
|
|
- **Unified API**: Combines memory-mapped loading with distributed sharding
|
|
- **Cross-shard Prefetching**: Optimizes data access across distributed shards
|
|
- **Batch Processing**: Efficient batch loading for distributed workers
|
|
- **Comprehensive Statistics**: Combined metrics from both memory-mapped and distributed components
|
|
|
|
**Implementation Highlights:**
|
|
- Worker-specific data loading with configurable batch sizes
|
|
- Automatic rebalancing with memory-mapped loader updates
|
|
- Performance efficiency scoring and cache optimization metrics
|
|
- Thread-safe concurrent access patterns
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ IntegratedDataLoader │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ ┌─────────────────────┐ ┌───────────────────────────┐ │
|
|
│ │ DistributedDataLoader│ │ MemoryMappedFileLoader │ │
|
|
│ │ │ │ │ │
|
|
│ │ • Sharding │ │ • Memory Mapping │ │
|
|
│ │ • Load Balancing │ │ • Lazy Loading │ │
|
|
│ │ • Fault Tolerance │ │ • Prefetching │ │
|
|
│ │ • Health Monitoring │ │ • Shared Memory │ │
|
|
│ └─────────────────────┘ └───────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Existing Preprocessing Infrastructure │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ StandardScaler │ MinMaxScaler │ Transformers │ Encoders │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## TDD Implementation Process
|
|
|
|
### Red Phase (Failing Tests)
|
|
1. **Memory-Mapped Loader Tests** (`memory_mapped_loader_tests.rs`):
|
|
- Basic loader creation and configuration
|
|
- File opening and memory mapping
|
|
- Lazy loading with page fault simulation
|
|
- Shared memory segment testing
|
|
- Prefetching strategy validation
|
|
- Concurrent access and thread safety
|
|
|
|
2. **Distributed Sharding Tests** (`distributed_sharding_tests.rs`):
|
|
- Loader initialization with multiple workers
|
|
- Different sharding strategies (round-robin, hash-based, size-aware)
|
|
- Dynamic rebalancing under load changes
|
|
- Fault tolerance and worker failure handling
|
|
- Performance metrics and statistics collection
|
|
|
|
3. **Integration Tests** (`integration_tests.rs`):
|
|
- Combined memory-mapped and distributed functionality
|
|
- Preprocessing transformer compatibility
|
|
- Concurrent access with multiple workers
|
|
- End-to-end pipeline validation
|
|
|
|
### Green Phase (Implementation)
|
|
- **Memory-mapped file loader** with complete lazy loading and prefetching
|
|
- **Distributed data sharding** with fault tolerance and rebalancing
|
|
- **Integration layer** combining both systems
|
|
- **Performance optimization** with comprehensive statistics
|
|
|
|
### Refactor Phase (Optimization)
|
|
- **Thread safety** improvements with proper synchronization
|
|
- **Memory efficiency** optimizations
|
|
- **Error handling** standardization
|
|
- **API consistency** across all components
|
|
|
|
## Integration with Existing Infrastructure
|
|
|
|
The new loaders are designed to work seamlessly with existing preprocessing transformers:
|
|
|
|
```rust
|
|
// Example: Using distributed loading with standard scaling
|
|
let mut loader = IntegratedDataLoader::new(config, workers);
|
|
loader.initialize(&data_files)?;
|
|
|
|
let batch = loader.load_worker_batch(worker_id, 0, &device)?;
|
|
let mut scaler = StandardScaler::new();
|
|
|
|
scaler.fit(&batch[0])?;
|
|
let transformed = scaler.transform(&batch[0])?;
|
|
```
|
|
|
|
## Performance Characteristics
|
|
|
|
### Memory-Mapped Loading
|
|
- **Memory Efficiency**: Only loads required pages, reducing memory footprint
|
|
- **Shared Access**: Multiple processes can share the same mapped memory
|
|
- **Cache Optimization**: Intelligent prefetching improves sequential access patterns
|
|
- **Scalability**: Handles files larger than available RAM
|
|
|
|
### Distributed Sharding
|
|
- **Load Balancing**: Automatic redistribution based on worker performance
|
|
- **Fault Tolerance**: Continues operation even with worker failures
|
|
- **Dynamic Adaptation**: Adjusts to changing load patterns
|
|
- **Horizontal Scaling**: Easy addition of new worker nodes
|
|
|
|
### Combined Performance
|
|
- **Throughput**: Optimized for high-throughput data processing
|
|
- **Latency**: Minimized access latency through prefetching and caching
|
|
- **Reliability**: Robust error handling and recovery mechanisms
|
|
- **Monitoring**: Comprehensive metrics for performance tuning
|
|
|
|
## Usage Examples
|
|
|
|
The implementation includes comprehensive examples in `examples.rs`:
|
|
|
|
1. **Basic Distributed Preprocessing**: Standard setup with worker configuration
|
|
2. **Fault Tolerance Demo**: Worker failure and recovery scenarios
|
|
3. **Performance Optimization**: Different prefetching strategies comparison
|
|
4. **Custom Preprocessing Pipeline**: Multi-stage transformation workflows
|
|
|
|
## File Structure
|
|
|
|
```
|
|
src/loaders/
|
|
├── mod.rs # Module exports and re-exports
|
|
├── memory_mapped.rs # Memory-mapped file loading implementation
|
|
├── distributed.rs # Distributed sharding implementation
|
|
├── integration.rs # Combined functionality layer
|
|
└── examples.rs # Comprehensive usage examples
|
|
|
|
tests/
|
|
├── memory_mapped_loader_tests.rs # Memory-mapping tests
|
|
├── distributed_sharding_tests.rs # Distributed sharding tests
|
|
└── integration_tests.rs # End-to-end integration tests
|
|
```
|
|
|
|
## Key Design Decisions
|
|
|
|
### 1. Safety First
|
|
- Zero `unsafe` code except for memory-mapping (which is inherently unsafe)
|
|
- Comprehensive error handling with custom error types
|
|
- Thread-safe design with appropriate synchronization primitives
|
|
|
|
### 2. Performance Focused
|
|
- Lock-free data structures where possible (`dashmap`, `crossbeam`)
|
|
- Efficient memory management with reference counting
|
|
- Optimized prefetching algorithms based on access patterns
|
|
|
|
### 3. Flexibility
|
|
- Configurable strategies for sharding and prefetching
|
|
- Pluggable fault tolerance policies
|
|
- Integration-friendly API design
|
|
|
|
### 4. Observability
|
|
- Comprehensive statistics and metrics collection
|
|
- Performance monitoring and analysis tools
|
|
- Debugging support with detailed error messages
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
- Individual component functionality
|
|
- Edge case handling
|
|
- Error condition validation
|
|
|
|
### Integration Tests
|
|
- Component interaction validation
|
|
- End-to-end workflow testing
|
|
- Performance characteristics verification
|
|
|
|
### Concurrent Tests
|
|
- Thread safety validation
|
|
- Race condition detection
|
|
- Deadlock prevention verification
|
|
|
|
## Dependencies Added
|
|
|
|
- `memmap2`: Memory-mapped file I/O
|
|
- `parking_lot`: High-performance synchronization primitives
|
|
- `dashmap`: Concurrent hash map for shared state
|
|
- `crossbeam`: Lock-free data structures and utilities
|
|
- `rayon`: Data parallelism support
|
|
- `once_cell`: Thread-safe lazy static initialization
|
|
- `nix`: Unix system programming utilities
|
|
|
|
## Future Enhancements
|
|
|
|
1. **Async I/O Support**: Integration with tokio for async file operations
|
|
2. **Compression Support**: On-the-fly decompression during loading
|
|
3. **Network Storage**: Support for remote file systems and object storage
|
|
4. **Advanced Analytics**: Machine learning-based access pattern prediction
|
|
5. **GPU Memory**: Direct GPU memory mapping for CUDA/ROCm workflows
|
|
|
|
## Conclusion
|
|
|
|
This implementation successfully enhances the rtx-preprocessing crate with production-ready memory-mapped file loading and distributed data sharding capabilities. The strict TDD approach ensures reliability and maintainability, while the comprehensive feature set addresses real-world requirements for high-performance data processing pipelines.
|
|
|
|
The design maintains full compatibility with existing preprocessing transformers while providing significant performance improvements for large-scale data processing scenarios. The implementation demonstrates mastery of Rust's ownership system, zero-cost abstractions, and systems programming capabilities. |