### Sequential Random Walk with FnMut Closure in Rust Source: https://github.com/orxfun/orx-parallel/blob/main/docs/using.md Demonstrates a sequential random walk computation using Rust's Iterator `map` method. This example showcases how `FnMut` closures can capture mutable references, such as a random number generator, which is safe in a single-threaded context. ```rust use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha20Rng; fn random_walk(rng: &mut impl Rng, position: i64, num_steps: usize) -> i64 { (0..num_steps).fold(position, |p, _| random_step(rng, p)) } fn random_step(rng: &mut impl Rng, position: i64) -> i64 { match rng.random_bool(0.5) { true => position + 1, // to right false => position - 1, // to left } } fn input_positions() -> Vec { (-10_000..=10_000).collect() } fn sequential() { let positions = input_positions(); let sum_initial_positions = positions.iter().sum::(); println!("sum_initial_positions = {sum_initial_positions}"); let mut rng = ChaCha20Rng::seed_from_u64(42); let final_positions: Vec<_> = positions .iter() .copied() .map(|position| random_walk(&mut rng, position, 100)) .collect(); let sum_final_positions = final_positions.iter().sum::(); println!("sum_final_positions = {sum_final_positions}"); } ``` -------------------------------- ### Parallel Computation with Iterators in Rust Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates how to parallelize common iterator operations like map, filter, and min_by_key using the `par()` method from the orx-parallel library. This allows for easy conversion of sequential iterator chains into parallel ones, significantly improving performance for computationally intensive tasks. The example uses a traveling salesperson problem simulation to showcase the difference between sequential and parallel execution. ```rust use orx_parallel::*; use rand::prelude::*; struct Tour(Vec); impl Tour { fn random(n: usize) -> Self { let mut cities: Vec<_> = (0..n).collect(); cities.shuffle(&mut rand::rng()); Self(cities) } fn not_in_standard_order(&self) -> bool { self.0.iter().enumerate().any(|(i, c)| i != *c) } fn duration(&self) -> usize { let mut total = 0; let links = self.0.iter().zip(self.0.iter().skip(1)); for (a, b) in links { total += (*a as i64 - *b as i64).abs() as usize; } total } } let num_tours = 1_000_000; let num_cities = 10; // sequential let best_tour = (0..num_tours) .map(|_| Tour::random(num_cities)) .filter(|t| t.not_in_standard_order()) .min_by_key(|t| t.duration()) .unwrap(); // parallel let best_tour = (0..num_tours) .par() // parallelized !! .map(|_| Tour::random(num_cities)) .filter(|t| t.not_in_standard_order()) .min_by_key(|t| t.duration()) .unwrap(); ``` -------------------------------- ### Parallel Computation with Explicit Mutable Variable (Rust) Source: https://github.com/orxfun/orx-parallel/blob/main/docs/using.md Demonstrates parallel computation using `par().copied().using().map().collect()`. It shows how to initialize a thread-local random number generator (RNG) using `using` and safely access it mutably within the `map` operation to perform a random walk. Each thread gets its own RNG instance seeded uniquely. ```rust fn parallel() { let positions = input_positions(); let sum_initial_positions = positions.iter().sum::(); println!("sum_initial_positions = {sum_initial_positions}"); let final_positions: Vec<_> = positions .par() // <-- parallel computation .copied() .using(|t_idx| ChaCha20Rng::seed_from_u64(42 * t_idx as u64)) // <-- explicit using .map(|rng, position| random_walk(rng, position, 100)) // <-- safe access to mutable rng .collect(); let sum_final_positions = final_positions.iter().sum::(); println!("sum_final_positions = {sum_final_positions}"); } ``` -------------------------------- ### Custom Thread Pool Integration for Parallel Operations in Rust Source: https://context7.com/orxfun/orx-parallel/llms.txt Shows how to integrate different thread pool implementations with orx-parallel for customizable parallel execution. This allows users to leverage existing thread pools like rayon or scoped_threadpool, or the default native thread pool when std is enabled. The example demonstrates switching between the default pool, rayon's ThreadPool, and scoped_threadpool. ```rust use orx_parallel::*; let inputs: Vec = (0..1000).collect(); // Default pool (native threads when std enabled) let sum1 = inputs.par().sum(); #[cfg(feature = "std")] { // Explicitly use StdDefaultPool let sum2 = inputs.par().with_pool(StdDefaultPool::default()).sum(); assert_eq!(sum1, sum2); } #[cfg(feature = "rayon-core")] { // Use rayon ThreadPool with 8 threads let pool = rayon_core::ThreadPoolBuilder::new() .num_threads(8) .build() .unwrap(); let sum3 = inputs.par().with_pool(&pool).sum(); assert_eq!(sum1, sum3); } #[cfg(feature = "scoped_threadpool")] { // Use scoped_threadpool with 4 threads let mut pool = scoped_threadpool::Pool::new(4); let sum4 = inputs.par().with_pool(&mut pool).sum(); assert_eq!(sum1, sum4); } ``` -------------------------------- ### Rust: Collect Metrics During Parallel Computation Source: https://github.com/orxfun/orx-parallel/blob/main/docs/using.md This Rust code snippet demonstrates how to collect metrics during parallel processing using the `orx-parallel` library. It defines `ThreadMetrics` to store per-thread data and `ComputationMetrics` to manage these metrics across threads. The `using` method is employed with an `unsafe` block to provide mutable access to thread-specific metrics, ensuring each thread gets its own metrics writer. The `map` and `filter` operations update these metrics while performing computations. ```rust use orx_parallel::*; use std::cell::UnsafeCell; const N: u64 = 10_000_000; const MAX_NUM_THREADS: usize = 8; // just some work fn fibonacci(n: u64) -> u64 { let mut a = 0; let mut b = 1; for _ in 0..n { let c = a + b; a = b; b = c; } a } #[derive(Default, Debug)] struct ThreadMetrics { thread_idx: usize, num_items_handled: usize, handled_42: bool, num_filtered_out: usize, } struct ThreadMetricsWriter<'a> { metrics_ref: &'a mut ThreadMetrics, } struct ComputationMetrics { thread_metrics: UnsafeCell<[ThreadMetrics; MAX_NUM_THREADS]>, } impl ComputationMetrics { fn new() -> Self { let mut thread_metrics: [ThreadMetrics; MAX_NUM_THREADS] = Default::default(); for i in 0..MAX_NUM_THREADS { thread_metrics[i].thread_idx = i; } Self { thread_metrics: UnsafeCell::new(thread_metrics), } } } impl ComputationMetrics { unsafe fn create_for_thread<'a>(&mut self, thread_idx: usize) -> ThreadMetricsWriter<'a> { // SAFETY: here we create a mutable variable to the thread_idx-th metrics // * If we call this method multiple times with the same index, // we create multiple mutable references to the same ThreadMetrics, // which would lead to a race condition. // * We must make sure that `create_for_thread` is called only once per thread. // * If we use `create_for_thread` within the `using` call to create mutable values // used by the threads, we are certain that the parallel computation // will only call this method once per thread; hence, it will not // cause the race condition. // * On the other hand, we must ensure that we do not call this method // externally. let array = unsafe { &mut *self.thread_metrics.get() }; ThreadMetricsWriter { metrics_ref: &mut array[thread_idx], } } } fn main() { let mut metrics = ComputationMetrics::new(); let input: Vec = (0..N).collect(); let sum = input .par() // SAFETY: we do not call `create_for_thread` externally; // it is safe if it is called only by the parallel computation. .using(|t| unsafe { metrics.create_for_thread(t) }) .map(|m: &mut ThreadMetricsWriter<'_>, i| { // collect some useful metrics m.metrics_ref.num_items_handled += 1; m.metrics_ref.handled_42 |= *i == 42; // actual work fibonacci((*i % 50) + 1) % 100 }) .filter(|m, i| { let is_even = i % 2 == 0; if !is_even { m.metrics_ref.num_filtered_out += 1; } is_even }) .num_threads(MAX_NUM_THREADS) .sum(); println!("\nINPUT-LEN = {N}"); println!("SUM = {sum}"); println!("\n\n"); println!("COLLECTED METRICS PER THREAD"); for metrics in metrics.thread_metrics.get_mut().iter() { println!("* {{metrics:?}}"); } let total_by_metrics: usize = metrics .thread_metrics .get_mut() .iter() .map(|x| x.num_items_handled) .sum(); println!("\n-> total num_items_handled by collected metrics: {{total_by_metrics:?}}\n"); assert_eq!(N as usize, total_by_metrics); } ``` -------------------------------- ### Parallel FlatMap and Nested Iteration in Rust Source: https://context7.com/orxfun/orx-parallel/llms.txt Illustrates how to use `flat_map` with orx-parallel for parallel processing that expands each input element into multiple output elements. This is useful for flattening nested iterators or generating multiple results from a single input in parallel. The examples show basic expansion and combining `flat_map` with filters and maps. ```rust use orx_parallel::*; // Expand each number into multiple values let expanded: Vec = (0..100) .par() .flat_map(|x| vec![x, x * 10, x * 100]) .collect(); assert_eq!(expanded.len(), 300); assert!(expanded.contains(&5)); assert!(expanded.contains(&50)); assert!(expanded.contains(&500)); // Combine with filters and maps let result: Vec = (1..=10) .par() .filter(|x| x % 2 == 0) .flat_map(|x| vec![x, x * 2]) .map(|x| format!("num_{}", x)) .collect(); assert!(result.contains(&"num_2".to_string())); assert!(result.contains(&"num_4".to_string())); assert_eq!(result.len(), 10); // 5 even numbers × 2 expansions ``` -------------------------------- ### Mutable State with Per-Thread RNG in Rust Source: https://context7.com/orxfun/orx-parallel/llms.txt Demonstrates using `using()` and `using_clone()` from orx-parallel to provide each thread with its own mutable state, such as a random number generator (RNG). This is useful for stateful parallel operations where each thread needs independent access to mutable resources. The example shows how to seed RNGs differently for `using()` and clone a single RNG for `using_clone()`. ```rust use orx_parallel::*; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha20Rng; fn fibonacci(n: u64) -> u64 { let mut a = 0; let mut b = 1; for _ in 0..n { let c = a + b; a = b; b = c; } a } let input: Vec = (1..10_000).collect(); // using() - create different RNG per thread with seed based on thread index let sum1 = input .par() .using(|thread_idx| ChaCha20Rng::seed_from_u64(thread_idx as u64 * 10)) .map(|rng, i| { let fib = fibonacci((i % 50) + 1) % 100; fib }) .filter(|rng: &mut ChaCha20Rng, val: &u64| { rng.random_bool(0.4) }) .map(|rng: &mut ChaCha20Rng, i: u64| { rng.random_range(0..=i) }) .sum(); // using_clone() - clone the same initial RNG for each thread let rng = ChaCha20Rng::seed_from_u64(42); let sum2 = input .into_par() .using_clone(rng) .map(|_, i| fibonacci((i % 50) + 1) % 100) .filter(|rng: &mut ChaCha20Rng, _| rng.random_bool(0.4)) .sum(); assert!(sum1 > 0 && sum2 > 0); ``` -------------------------------- ### Parallel Random Walk Attempt with FnMut Closure in Rust (Will Not Compile) Source: https://github.com/orxfun/orx-parallel/blob/main/docs/using.md Illustrates an attempt to perform a parallel random walk using orx-parallel's `par()` iterator. This example is intended to show that closures capturing mutable references (like `rng`) will fail to compile due to `ParIter` requiring `Fn` closures to prevent race conditions. ```rust fn parallel() { let positions = input_positions(); let sum_initial_positions = positions.iter().sum::(); println!("sum_initial_positions = {sum_initial_positions}"); let mut rng = ChaCha20Rng::seed_from_u64(42); let final_positions: Vec<_> = positions .par() // <-- parallel computation .copied() .map(|position| random_walk(&mut rng, position, 100)) // <-- does not compile!! .collect(); let sum_final_positions = final_positions.iter().sum::(); println!("sum_final_positions = {sum_final_positions}"); } ``` -------------------------------- ### Parallel Recursive Iterator for Tree Traversal in Rust Source: https://context7.com/orxfun/orx-parallel/llms.txt Enables parallelization over non-linear data structures like trees and graphs using orx-parallel's recursive iterator capabilities. It supports dynamic task generation, allowing for efficient traversal and reduction of tree-like structures. The example demonstrates collecting, filtering, and summing node data in parallel. ```rust use orx_parallel::*; // Define a simple tree node #[derive(Debug)] struct Node { data: T, children: Vec>, } impl Node { fn new(data: T, children: Vec>) -> Self { Self { data, children } } fn leaf(data: T) -> Self { Self::new(data, vec![]) } } // Create a sample tree let tree = Node::new( 1, vec![ Node::new(2, vec![ Node::leaf(4), Node::leaf(5), ]), Node::new(3, vec![ Node::leaf(6), Node::leaf(7), Node::leaf(8), ]), ], ); // Define how to extend the iteration recursively fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) { queue.extend(&node.children); } // Parallel tree traversal and reduction let sum: i32 = [&tree] .into_par_rec(extend) .map(|node| node.data) .sum(); assert_eq!(sum, 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8); // Collect all node values let values: Vec = [&tree] .into_par_rec(extend) .map(|node| node.data) .collect(); assert_eq!(values.len(), 8); // Filter and process tree nodes let filtered_sum: i32 = [&tree] .into_par_rec(extend) .filter(|node| node.data % 2 == 0) .map(|node| node.data * 10) .sum(); assert_eq!(filtered_sum, (2 + 4 + 6 + 8) * 10); ``` -------------------------------- ### Benchmarking orx-parallel with Cargo Command Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Shows how to run benchmarks for the orx-parallel library using a Cargo command, including enabling the `generic_iterator` feature for experiments. ```bash ```bash cargo run --release --features generic_iterator --example benchmark_collect -- --len 123456 --num-repetitions 10 ``` ``` -------------------------------- ### Parallel Iteration Over Collections in Rust Source: https://context7.com/orxfun/orx-parallel/llms.txt Illustrates parallel iteration over standard Rust collections like `Vec` and slices, supporting references, mutable references, and owned values. Demonstrates `.par()`, `.into_par()`, and `.for_each()` for different use cases. Requires `orx_parallel`. ```rust use orx_parallel::*; // Parallel over Vec references let vec: Vec = (0..1000).collect(); let sum: u64 = vec.par().map(|x| x * x).sum(); // Parallel over Vec consuming it (owned values) let vec2: Vec = (0..1000).collect(); let transformed: Vec = vec2.into_par().map(|x| x * 2).collect(); // Parallel over mutable slice let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8]; data.as_mut_slice() .into_par() .filter(|x| **x % 2 == 0) .for_each(|x| *x *= 10); assert_eq!(data, vec![1, 20, 3, 40, 5, 60, 7, 80]); ``` -------------------------------- ### Parallel Reduction Operations: sum, product, min, max, reduce (Rust) Source: https://context7.com/orxfun/orx-parallel/llms.txt Demonstrates various parallel reduction operations, including sum, product, finding minimum and maximum elements, and custom reductions using a combining function. Supports finding min/max based on a key. ```rust use orx_parallel::*; let data: Vec = vec![3, 7, 2, 9, 4, 1, 8, 5, 6]; // sum and product let sum: i32 = data.par().sum(); assert_eq!(sum, 45); let product: i32 = data.par().product(); assert_eq!(product, 362880); // min and max let min = data.par().min(); assert_eq!(min, Some(&1)); let max = data.par().max(); assert_eq!(max, Some(&9)); // min_by_key and max_by_key #[derive(Debug, Clone, PartialEq)] struct Item { id: i32, value: String } let items: Vec = (0..100) .map(|i| Item { id: i, value: format!("v{{}}", i * 10) }) .collect(); let min_item = items.par().min_by_key(|item| item.id); assert_eq!(min_item.unwrap().id, 0); // Custom reduce with accumulator function let custom_reduce = data .par() .map(|x| x * 2) .reduce(|a, b| a + b); assert_eq!(custom_reduce, Some(90)); ``` -------------------------------- ### Rust: Short-circuiting with '?' Operator in Fallible Computations Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates the use of Rust's '?' operator for concisely handling fallible computations. It allows focusing on the success path, with any error causing an early return from the function. ```rust fn try_to_parse() -> Result { let x: i32 = "123".parse()?; // x = 123 let y: i32 = "24a".parse()?; // returns an Err() immediately Ok(x + y) // Doesn't run. } ``` -------------------------------- ### Configure orx-parallel Computations in Rust Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates how to configure parallel computations using `NumThreads` and `ChunkSize` in Rust with the orx-parallel library. It shows default settings, explicit thread and chunk size configurations, and combinations of both. ```rust use orx_parallel::*; use std::num::NonZeroUsize; let n = 1024; _ = (0..n).par().sum(); // NumThreads::Auto & ChunkSize::Auto _ = (0..n).par().num_threads(4).sum(); // <= 4 threads _ = (0..n).par().num_threads(1).sum(); // sequential _ = (0..n).par().num_threads(0).sum(); // shorthand for NumThreads::Auto _ = (0..n).par().chunk_size(64).sum(); // chunks of exactly 64 elements let c = ChunkSize::Min(NonZeroUsize::new(16).unwrap()); _ = (0..n).par().chunk_size(c).sum(); // chunks of at least 16 elements _ = (0..n).par().num_threads(4).chunk_size(16).sum(); // set both params ``` -------------------------------- ### Parallel Channel Communication using `using_clone` (Rust) Source: https://github.com/orxfun/orx-parallel/blob/main/docs/using.md Demonstrates using `using_clone` with channels for parallel data distribution. A `Sender` end of an MPSC channel is cloned and sent to each parallel task using `using_clone`. Each task then sends its data (`x`) through the channel. The main thread collects the results from the `Receiver` end, sorts them, and asserts the expected output. ```rust use orx_parallel::*; use std::sync::mpsc::channel; let (sender, receiver) = channel(); (0..5) .into_par() .using_clone(sender) .for_each(|s, x| s.send(x).unwrap()); let mut res: Vec<_> = receiver.iter().collect(); res.sort(); assert_eq!(&res[..], &[0, 1, 2, 3, 4]) ``` -------------------------------- ### Parallelizing HashSet Iterators with orx-parallel Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates two methods to parallelize computations over a HashSet using its iterator. Method (ii) uses `iter_into_par()` directly on the iterator, while method (i) first collects elements into a Vec and then parallelizes over the vector. ```rust ```rust // Method (ii): Over References hashset.iter().iter_into_par(); // Method (ii): Over Owned Values hashset.into_iter().iter_into_par(); // Method (i): Over References hashset.iter().collect::>().par(); // Method (i): Over Owned Values hashset.into_iter().collect::>().into_par(); ``` ``` -------------------------------- ### Basic Parallel Iterator Source: https://context7.com/orxfun/orx-parallel/llms.txt Demonstrates how to convert a sequential range into a parallel computation using the `.par()` method for parallel map, filter, and reduce operations. ```APIDOC ## Basic Parallel Iterator - Converting Sequential to Parallel Transforms a sequential range into a parallel computation using the `par()` method to enable parallel map, filter, and reduce operations. ### Method GET (Implicit via iterator usage) ### Endpoint N/A (Iterator-based) ### Parameters None ### Request Example ```rust use orx_parallel::*; // Sequential computation let sum_sequential = (0..1_000_000) .map(|x| x * 2) .filter(|x| x % 3 == 0) .sum::(); // Parallel computation - simply add .par() let sum_parallel = (0..1_000_000) .par() .map(|x| x * 2) .filter(|x| x % 3 == 0) .sum(); assert_eq!(sum_sequential, sum_parallel); ``` ### Response #### Success Response (200) N/A (Iterator-based computation) #### Response Example N/A ``` -------------------------------- ### Setting Chunk Size in Rust Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates how to explicitly set the chunk size for parallel operations in Rust using the `par.chunk_size()` method. This allows fine-tuning performance by controlling the number of items processed per parallel task. It highlights choices like `1` for minimizing heterogeneity cost or `0`/`Auto` for heuristic-based optimization. ```rust use orx_parallel::prelude::*; let data = vec![1, 2, 3, 4, 5]; // Option 1: Set chunk size to 1 let result1: Vec<_> = data.par().chunk_size(1).map(|x| x * 2).collect(); // Option 2: Use automatic chunk size (heuristic) let result2: Vec<_> = data.par().chunk_size(0).map(|x| x * 2).collect(); // Option 3: Explicitly use Auto enum let result3: Vec<_> = data.par().chunk_size(ChunkSize::Auto).map(|x| x * 2).collect(); ``` -------------------------------- ### Control Iteration Order in Parallel with orx-parallel Source: https://context7.com/orxfun/orx-parallel/llms.txt Illustrates how to control iteration order in parallel processing using `orx-parallel`. It contrasts `IterationOrder::Ordered` (default) with `IterationOrder::Arbitrary` for performance, showing the need to sort arbitrary results if order is required. Requires the `orx-parallel` crate. ```rust use orx_parallel::prelude::*; use orx_parallel::IterationOrder; let input: Vec = (0..1000).collect(); // Ordered iteration (default) - maintains order in collect let ordered: Vec = input .par() .iteration_order(IterationOrder::Ordered) .map(|x| x * 2) .collect(); assert_eq!(ordered[0], 0); assert_eq!(ordered[1], 2); assert_eq!(ordered[500], 1000); // Arbitrary iteration - faster but no order guarantee let mut arbitrary: Vec = input .into_par() .iteration_order(IterationOrder::Arbitrary) .map(|x| x * 2) .collect(); arbitrary.sort(); // need to sort if order matters assert_eq!(arbitrary, ordered); ``` -------------------------------- ### Configure Thread Count and Chunk Size for Parallel Execution (Rust) Source: https://context7.com/orxfun/orx-parallel/llms.txt Demonstrates how to configure parallel execution by explicitly setting the number of threads and optimizing chunk sizes for performance. Supports default, fixed thread counts, and minimum chunk sizes. ```rust use orx_parallel::*; use std::num::NonZeroUsize; let n = 100_000; // Default: auto threads and auto chunk size let sum1 = (0..n).par().sum::(); // Limit to 4 threads let sum2 = (0..n).par().num_threads(4).sum::(); // Sequential execution (1 thread) let sum3 = (0..n).par().num_threads(1).sum::(); // Set exact chunk size of 64 elements let sum4 = (0..n).par().chunk_size(64).sum::(); // Set minimum chunk size (executor may use larger) let chunk = ChunkSize::Min(NonZeroUsize::new(16).unwrap()); let sum5 = (0..n).par().chunk_size(chunk).sum::(); // Combine both parameters let sum6 = (0..n) .par() .num_threads(4) .chunk_size(32) .sum::(); assert_eq!(sum1, sum2); assert_eq!(sum2, sum3); assert_eq!(sum3, sum4); assert_eq!(sum4, sum5); assert_eq!(sum5, sum6); ``` -------------------------------- ### Early Exit Parallel Search Operations: find and find_any (Rust) Source: https://context7.com/orxfun/orx-parallel/llms.txt Implements parallel search operations that allow early termination. `find` returns the first element matching a predicate while respecting iteration order, whereas `find_any` returns any matching element, potentially offering faster performance. Also includes `any` and `all` for predicate checks. ```rust use orx_parallel::*; let data: Vec = (0..1_000_000).collect(); // find: returns first match respecting iteration order let found = data .par() .map(|x| x * 2) .filter(|x| x % 7 == 0) .find(|x| x > &1000); assert_eq!(found, Some(1008)); // find_any: returns any match (faster, no order guarantee) let found_any = data .par() .flat_map(|x| vec![x, x * 2, x * 3]) .find_any(|x| x == &123_456); assert_eq!(found_any, Some(123_456)); // any: checks if any element satisfies predicate let has_large = data.par().any(|x| x > &900_000); assert!(has_large); // all: checks if all elements satisfy predicate let all_positive = data.par().all(|x| x < 2_000_000); assert!(all_positive); ``` -------------------------------- ### Collecting Results into Vectors Source: https://context7.com/orxfun/orx-parallel/llms.txt Shows how to collect the results of parallel computations into standard `Vec` or specialized `SplitVec` for performance. ```APIDOC ## Collecting Results into Vectors Parallel collection of transformed data into Vec or specialized containers like SplitVec for improved performance. ### Method GET (Implicit via iterator usage) ### Endpoint N/A (Iterator-based) ### Parameters None ### Request Example ```rust use orx_parallel::*; let input: Vec = (0..10_000).collect(); // Collect into Vec let results: Vec = input .par() .map(|x| x * 2) .filter(|x| x % 5 != 0) .map(|x| format!("value_{}", x)) .collect(); // Collect into SplitVec to avoid memory copies let results_split: orx_split_vec::SplitVec = input .into_par() .map(|x| x * 2) .filter(|x| x % 5 != 0) .map(|x| format!("value_{}", x)) .collect(); assert_eq!(results.len(), results_split.len()); ``` ### Response #### Success Response (200) N/A (Iterator-based computation) #### Response Example N/A ``` -------------------------------- ### Count Elements in Parallel with orx-parallel Source: https://context7.com/orxfun/orx-parallel/llms.txt Demonstrates parallel counting of elements in a vector using `orx-parallel`. It shows counting all elements, counting after filtering, and counting after flat mapping, requiring the `orx-parallel` crate. ```rust use orx_parallel::prelude::*; let data: Vec = (0..10_000).collect(); // Count all elements let count = data.par().count(); assert_eq!(count, 10_000); // Count after filtering let even_count = data .par() .filter(|x| x % 2 == 0) .count(); assert_eq!(even_count, 5_000); // Count after flatmap let expanded_count = data .par() .flat_map(|x| vec![x, x * 2, x * 3]) .count(); assert_eq!(expanded_count, 30_000); ``` -------------------------------- ### Setting Default and Custom Thread Pools in Rust Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates how to use the default thread pool (StdDefaultPool when 'std' feature is enabled) and explicitly set custom thread pools like scoped_threadpool, rayon-core, and yastl for parallel computations in Rust. It shows the usage of the `.par().sum()` and `.par().with_pool()` methods. ```rust use orx_parallel::*; let inputs: Vec<_> = (0..42).collect(); // uses the DefaultPool // assuming "std" enabled, StdDefaultPool will be used; i.e., native threads let sum = inputs.par().sum(); // equivalent to: #[cfg(feature = "std")] { let sum2 = inputs.par().with_pool(StdDefaultPool::default()).sum(); assert_eq!(sum, sum2); } #[cfg(not(miri))] #[cfg(feature = "scoped_threadpool")] { let mut pool = scoped_threadpool::Pool::new(8); // uses the scoped_threadpool::Pool created with 8 threads let sum2 = inputs.par().with_pool(&mut pool).sum(); assert_eq!(sum, sum2); } #[cfg(not(miri))] #[cfg(feature = "rayon-core")] { let pool = rayon_core::ThreadPoolBuilder::new() .num_threads(8) .build() .unwrap(); // uses the rayon-core::ThreadPool created with 8 threads let sum2 = inputs.par().with_pool(&pool).sum(); assert_eq!(sum, sum2); } #[cfg(not(miri))] #[cfg(feature = "yastl")] { let pool = YastlPool::new(8); // uses the yastl::Pool created with 8 threads let sum2 = inputs.par().with_pool(&pool).sum(); assert_eq!(sum, sum2); } ``` -------------------------------- ### Parallel Mutable Iteration Source: https://context7.com/orxfun/orx-parallel/llms.txt Explains how to achieve parallel iteration with mutable references for in-place transformations using `par_mut()` or `into_par()` on mutable slices. ```APIDOC ## Parallel Mutable Iteration Enables parallel iteration with mutable references for in-place transformations using `par_mut()` or `into_par()` on mutable slices. ### Method GET (Implicit via iterator usage) ### Endpoint N/A (Iterator-based) ### Parameters None ### Request Example ```rust use orx_parallel::*; const N: usize = 1_000_000; // Using par_mut() on Vec let mut vec: Vec = (0..N).collect(); vec.par_mut() .filter(|x| **x != 42) .for_each(|x| *x *= 0); let sum = vec.par().sum(); assert_eq!(sum, 42); // Using into_par() on mutable slice let mut data: Vec = (0..1000).collect(); let slice = data.as_mut_slice(); slice.into_par() .map(|x| *x *= 2) .count(); assert_eq!(data[10], 20); ``` ### Response #### Success Response (200) N/A (Iterator-based computation) #### Response Example N/A ``` -------------------------------- ### Parallelizing Arbitrary Iterators in Rust Source: https://context7.com/orxfun/orx-parallel/llms.txt Demonstrates parallelizing iterators from non-standard collections like `HashMap` using `iter_into_par()`. Shows parallel sum operations on values and parallel mutable iteration over values. Requires `orx_parallel`. ```rust use orx_parallel::*; use std::collections::HashMap; // Parallelize HashMap values let mut map: HashMap = (0..1_000) .map(|x| (x, x * 10)) .collect(); // Parallel sum over values let sum: usize = map.values().iter_into_par().sum(); assert_eq!(sum, (0..1_000).map(|x| x * 10).sum::()); // Parallel mutable iteration map.values_mut() .iter_into_par() .filter(|x| **x != 420) .for_each(|x| *x = 0); assert_eq!(map.values().iter_into_par().sum::(), 420); ``` -------------------------------- ### Rust: Collecting Iterator Items into Different Containers Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Illustrates the `collect` method in Rust, which can gather iterator items into various container types like `Vec` and `HashSet`. ```rust let into_vec: Vec = (0..10).collect(); let into_set: std::collections::HashSet = (0..10).collect(); ``` -------------------------------- ### Parallel Iteration over Collections Source: https://context7.com/orxfun/orx-parallel/llms.txt Details how to perform parallel iteration directly on collections like `Vec`, `VecDeque`, and slices, supporting references, mutable references, and owned values. ```APIDOC ## Parallel Iteration over Collections Direct parallelization of Vec, VecDeque, and slices with support for references, mutable references, and owned values. ### Method GET (Implicit via iterator usage) ### Endpoint N/A (Iterator-based) ### Parameters None ### Request Example ```rust use orx_parallel::*; // Parallel over Vec references let vec: Vec = (0..1000).collect(); let sum: u64 = vec.par().map(|x| x * x).sum(); // Parallel over Vec consuming it (owned values) let vec2: Vec = (0..1000).collect(); let transformed: Vec = vec2.into_par().map(|x| x * 2).collect(); // Parallel over mutable slice let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8]; data.as_mut_slice() .into_par() .filter(|x| **x % 2 == 0) .for_each(|x| *x *= 10); assert_eq!(data, vec![1, 20, 3, 40, 5, 60, 7, 80]); ``` ### Response #### Success Response (200) N/A (Iterator-based computation) #### Response Example N/A ``` -------------------------------- ### Parallelizing Arbitrary Iterators Source: https://context7.com/orxfun/orx-parallel/llms.txt Covers the conversion of standard Rust `Iterator`s into parallel iterators using `iter_into_par()`, applicable to data structures like `HashMap` and `HashSet`. ```APIDOC ## Parallelizing Arbitrary Iterators Converts any standard Iterator into a parallel iterator using `iter_into_par()`, enabling parallelization of HashMap, HashSet, and custom iterators. ### Method GET (Implicit via iterator usage) ### Endpoint N/A (Iterator-based) ### Parameters None ### Request Example ```rust use orx_parallel::*; use std::collections::HashMap; // Parallelize HashMap values let mut map: HashMap = (0..1_000) .map(|x| (x, x * 10)) .collect(); // Parallel sum over values let sum: usize = map.values().iter_into_par().sum(); assert_eq!(sum, (0..1_000).map(|x| x * 10).sum::()); // Parallel mutable iteration map.values_mut() .iter_into_par() .filter(|x| **x != 420) .for_each(|x| *x = 0); assert_eq!(map.values().iter_into_par().sum::(), 420); ``` ### Response #### Success Response (200) N/A (Iterator-based computation) #### Response Example N/A ``` -------------------------------- ### Parallel Mutable Iteration in Rust Source: https://context7.com/orxfun/orx-parallel/llms.txt Explains how to perform in-place transformations using parallel iteration on mutable data structures. Covers `par_mut()` for `Vec` and `into_par()` on mutable slices. Demonstrates modifying elements concurrently. Requires `orx_parallel`. ```rust use orx_parallel::*; const N: usize = 1_000_000; // Using par_mut() on Vec let mut vec: Vec = (0..N).collect(); vec.par_mut() .filter(|x| **x != 42) .for_each(|x| *x *= 0); let sum = vec.par().sum(); assert_eq!(sum, 42); // Using into_par() on mutable slice let mut data: Vec = (0..1000).collect(); let slice = data.as_mut_slice(); slice.into_par() .map(|x| *x *= 2) .count(); assert_eq!(data[10], 20); ``` -------------------------------- ### Parallelizing Vec, VecDeque, Slices, and Ranges in Rust Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates how to directly obtain parallel iterators from standard Rust collections like Vec, VecDeque, slices, and ranges. This approach leverages the specific structure of these collections for high performance. It covers parallel iteration over references, mutable references, and owned values, as well as specialized methods like `par_drain`. ```rust use orx_parallel::prelude::*; let v = vec![1, 2, 3, 4, 5]; let sum: i32 = v.par().sum(); let mut vd = std::collections::VecDeque::from(vec![10, 20, 30]); let sum_vd: i32 = vd.par().sum(); let s = &[100, 200, 300]; let sum_s: i32 = s.par().sum(); let r = 0..10; let sum_r: i32 = r.par().sum(); // Example for mutable references let mut v_mut = vec![1, 2, 3]; v_mut.par_mut().for_each(|x| *x *= 2); // Example for par_drain let mut v_drain = vec![1, 2, 3, 4, 5]; let drained_elements: Vec<_> = v_drain.par_drain(1..3).collect(); // Drains elements at index 1 and 2 ``` -------------------------------- ### Parallel Iterator Sharing Sender with `using_clone` Source: https://github.com/orxfun/orx-parallel/blob/main/README.md This Rust code snippet illustrates the `using_clone` transformation for parallel iterators. It takes a `sender` (from a channel) and clones it, providing each thread with its own mutable copy. The `for_each` method then uses the cloned sender to send data concurrently, demonstrating a convenient way to share mutable resources. ```rust let (sender, receiver) = channel(); (0..5) .into_par() .using_clone(sender) .for_each(|s, x| s.send(x).unwrap()); let mut res: Vec<_> = receiver.iter().collect(); ``` -------------------------------- ### Parallel Recursive Iteration over Trees with orx-parallel Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Illustrates parallelizing computations over tree structures using `into_par_rec`. The `extend` function defines how to recursively add children to the processing queue for a parallel recursive iterator. ```rust ```rust struct Node { data: T, children: Vec>, } fn extend<'a>(node: &&'a Node, queue: &Queue<&'a Node>) { queue.extend(&node.children); } // Example computation: map data and sum let sum_of_mapped_values = [root].into_par_rec(extend).map(map).sum(); // Example computation: filter, map, and collect let collected_values = [root].into_par_rec(extend).filter(filter).map(map).collect(); ``` ``` -------------------------------- ### Rust: Parallel Summation with Fallible Iterator Transformations Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Shows a parallel computation using `orx-parallel` where a parallel iterator of parsing results is transformed into a fallible parallel iterator. Subsequent operations like `map`, `filter`, `flat_map`, and `sum` operate on the success type, and the final `sum` returns a `Result` that short-circuits on the first parsing error. ```rust use orx_parallel::* use std::num::ParseIntError; let sum: Result = vec!["7", "2", "34"] .into_par() .map(|x| x.parse::()) // Item = Result .into_fallible_result() // we are only working with success type after this point .map(|x| x + 1) .filter(|x| x % 2 == 0) .flat_map(|x| [x, x + 1, x + 2]) .sum(); // returns Result, rather than i32 assert_eq!(sum, Ok(27)); let sum: Result = vec!["7", "!!!", "34"] .into_par() .map(|x| x.parse::()) .into_fallible_result() .map(|x| x + 1) .filter(|x| x % 2 == 0) .flat_map(|x| [x, x + 1, x + 2]) .sum(); assert!(sum.is_err()); ``` -------------------------------- ### Rust: Parallel Collection with Fallible Iterator Conversion Source: https://github.com/orxfun/orx-parallel/blob/main/README.md Demonstrates how to use the `orx-parallel` crate to perform parallel collection of fallible operations. It converts a parallel iterator of `Result`s into a fallible parallel iterator using `into_fallible_result()` before collecting. ```rust use orx_parallel::* use std::num::ParseIntError; let collect: Result, ParseIntError> = vec!["7", "2", "34"] .into_par() .map(|x| x.parse::()) .into_fallible_result() // <-- explicit transformation to fallible iterator .collect(); ```