fdars_core/
parallel.rs

1//! Parallel iteration abstraction for WASM compatibility.
2//!
3//! This module provides conditional parallel/sequential iteration based on
4//! the `parallel` feature flag. On native targets with the `parallel` feature,
5//! uses rayon for multi-threaded execution. On WASM or without the feature,
6//! falls back to sequential iteration.
7//!
8//! # Usage
9//!
10//! Use the `iter_maybe_parallel!` macro to conditionally parallelize iteration:
11//!
12//! ```ignore
13//! use crate::parallel::iter_maybe_parallel;
14//!
15//! let results: Vec<_> = iter_maybe_parallel!((0..n))
16//!     .map(|i| expensive_computation(i))
17//!     .collect();
18//! ```
19
20/// Macro for conditionally parallel iteration over ranges.
21///
22/// When the `parallel` feature is enabled, uses `into_par_iter()`.
23/// Otherwise, uses `into_iter()` for sequential execution.
24///
25/// # Examples
26///
27/// ```ignore
28/// use crate::iter_maybe_parallel;
29///
30/// // Range iteration
31/// let results: Vec<_> = iter_maybe_parallel!((0..100))
32///     .map(|i| i * 2)
33///     .collect();
34///
35/// // Vec iteration (consuming)
36/// let vec = vec![1, 2, 3];
37/// let results: Vec<_> = iter_maybe_parallel!(vec)
38///     .map(|x| x * 2)
39///     .collect();
40/// ```
41#[macro_export]
42macro_rules! iter_maybe_parallel {
43    ($expr:expr) => {{
44        #[cfg(feature = "parallel")]
45        {
46            use rayon::iter::IntoParallelIterator;
47
48            IntoParallelIterator::into_par_iter($expr)
49        }
50        #[cfg(not(feature = "parallel"))]
51        {
52            IntoIterator::into_iter($expr)
53        }
54    }};
55}
56
57/// Macro for conditionally parallel reference iteration over slices.
58///
59/// When the `parallel` feature is enabled, uses `par_iter()`.
60/// Otherwise, uses `iter()` for sequential execution.
61#[macro_export]
62macro_rules! slice_maybe_parallel {
63    ($expr:expr) => {{
64        #[cfg(feature = "parallel")]
65        {
66            use rayon::prelude::*;
67            $expr.par_iter()
68        }
69        #[cfg(not(feature = "parallel"))]
70        {
71            $expr.iter()
72        }
73    }};
74}
75
76/// Macro for conditionally parallel mutable iteration over slices.
77///
78/// When the `parallel` feature is enabled, uses `par_iter_mut()`.
79/// Otherwise, uses `iter_mut()` for sequential execution.
80#[macro_export]
81macro_rules! slice_maybe_parallel_mut {
82    ($expr:expr) => {{
83        #[cfg(feature = "parallel")]
84        {
85            use rayon::prelude::*;
86            $expr.par_iter_mut()
87        }
88        #[cfg(not(feature = "parallel"))]
89        {
90            $expr.iter_mut()
91        }
92    }};
93}
94
95/// Macro for parallel/sequential chunks iteration on mutable slices.
96///
97/// # Example
98/// ```ignore
99/// use crate::maybe_par_chunks_mut;
100///
101/// maybe_par_chunks_mut!(data, chunk_size, |chunk| {
102///     // process chunk
103/// });
104/// ```
105#[macro_export]
106macro_rules! maybe_par_chunks_mut {
107    ($slice:expr, $chunk_size:expr, $closure:expr) => {{
108        #[cfg(feature = "parallel")]
109        {
110            use rayon::prelude::*;
111            $slice.par_chunks_mut($chunk_size).for_each($closure);
112        }
113        #[cfg(not(feature = "parallel"))]
114        {
115            $slice.chunks_mut($chunk_size).for_each($closure);
116        }
117    }};
118}
119
120/// Macro for enumerated parallel/sequential chunks iteration.
121///
122/// # Example
123/// ```ignore
124/// use crate::maybe_par_chunks_mut_enumerate;
125///
126/// maybe_par_chunks_mut_enumerate!(data, chunk_size, |(idx, chunk)| {
127///     // process chunk at index idx
128/// });
129/// ```
130#[macro_export]
131macro_rules! maybe_par_chunks_mut_enumerate {
132    ($slice:expr, $chunk_size:expr, $closure:expr) => {{
133        #[cfg(feature = "parallel")]
134        {
135            use rayon::prelude::*;
136            $slice
137                .par_chunks_mut($chunk_size)
138                .enumerate()
139                .for_each($closure);
140        }
141        #[cfg(not(feature = "parallel"))]
142        {
143            $slice
144                .chunks_mut($chunk_size)
145                .enumerate()
146                .for_each($closure);
147        }
148    }};
149}
150
151// Re-export macros at module level
152pub use iter_maybe_parallel;
153pub use maybe_par_chunks_mut;
154pub use maybe_par_chunks_mut_enumerate;
155pub use slice_maybe_parallel;
156pub use slice_maybe_parallel_mut;