#[cfg(all(feature = "memory_efficient", feature = "parallel"))]
#[allow(dead_code)]
fn main() {
use scirs2_core::memory_efficient::{
create_mmap, AccessMode, ChunkingStrategy, MemoryMappedChunks, MemoryMappedChunksParallel,
};
use scirs2_core::ndarray::Array1;
use std::time::Instant;
println!("Memory-Mapped Array Parallel Processing Example");
println!("==============================================");
let size = 10_000_000;
let data = Array1::<f64>::linspace(0.0, (size as f64) - 1.0, size);
println!("Created array with {} elements", size);
let temp_file = tempfile::NamedTempFile::new().expect("Operation failed");
let temp_path = temp_file.path();
println!("Created temporary file at: {}", temp_path.display());
let mut mmap =
create_mmap(&data, temp_path, AccessMode::ReadWrite, 0).expect("Operation failed");
println!("Created memory-mapped array");
println!("\nProcessing chunks sequentially...");
let start = Instant::now();
let chunk_size = 100_000;
let sequential_sums =
mmap.process_chunks(ChunkingStrategy::Fixed(chunk_size), |chunk, chunk_idx| {
let result: f64 = chunk.iter().map(|&x| x * x).sum();
if chunk_idx % 20 == 0 {
println!(
"Sequential - Processed chunk {}: sum of squares = {:.2}",
chunk_idx, result
);
}
result
});
let sequential_time = start.elapsed();
println!("Sequential processing time: {:?}", sequential_time);
println!("Number of chunks processed: {}", sequential_sums.len());
println!("\nProcessing chunks in parallel...");
let start = Instant::now();
let parallel_sums =
mmap.process_chunks_parallel(ChunkingStrategy::Fixed(chunk_size), |chunk, chunk_idx| {
let result: f64 = chunk.iter().map(|&x| x * x).sum();
if chunk_idx % 20 == 0 {
println!(
"Parallel - Processed chunk {}: sum of squares = {:.2}",
chunk_idx, result
);
}
result
});
let parallel_time = start.elapsed();
println!("Parallel processing time: {:?}", parallel_time);
println!("Number of chunks processed: {}", parallel_sums.len());
let speedup = sequential_time.as_secs_f64() / parallel_time.as_secs_f64();
println!("\nSpeedup with parallel processing: {:.2}x", speedup);
let sequential_total: f64 = sequential_sums.iter().sum();
let parallel_total: f64 = parallel_sums.iter().sum();
println!("Sequential total: {:.2}", sequential_total);
println!("Parallel total: {:.2}", parallel_total);
assert!(
(sequential_total - parallel_total).abs() < 1e-10,
"Sequential and parallel results differ!"
);
println!("\nModifying chunks in parallel...");
let start = Instant::now();
mmap.process_chunks_mut_parallel(ChunkingStrategy::Fixed(chunk_size), |chunk, chunk_idx| {
for elem in chunk.iter_mut() {
*elem = *elem * *elem;
}
if chunk_idx % 20 == 0 {
println!("Modified chunk {}", chunk_idx);
}
});
let mutation_time = start.elapsed();
println!("Parallel mutation time: {:?}", mutation_time);
println!("\nVerifying the mutation worked...");
let sum_after_mutation: f64 = mmap
.process_chunks(ChunkingStrategy::Fixed(chunk_size), |chunk, _chunk_idx| {
chunk.iter().sum::<f64>()
})
.iter()
.sum();
println!("Sum after mutation: {:.2}", sum_after_mutation);
assert!(
(sum_after_mutation - sequential_total).abs() < 1e-10,
"Mutation did not produce expected results!"
);
println!("\nSuccessfully completed all operations!");
}
#[cfg(not(all(feature = "memory_efficient", feature = "parallel")))]
#[allow(dead_code)]
fn main() {
println!("This example requires the 'memory_efficient' and 'parallel' features.");
println!("Please run with:");
println!("cargo run --example memory_mapped_parallel --features=\"memory_efficient parallel\"");
}