pub struct RunnerWithPool<P, R = DefaultExecutor>where
P: ParThreadPool,
R: ParallelExecutor,{ /* private fields */ }
Expand description
Parallel runner with a given pool of type P
and parallel executor of R
.
A RunnerWithPool
can always be created from owned pool
implementing ParThreadPool
, but also from
&pool
in most cases,&mut pool
in others.
Note that default parallel runner; i.e., DefaultRunner
is:
RunnerWithPool<StdDefaultPool>
when “std” feature is enabled,RunnerWithPool<SequentialPool>
when “std” feature is disabled.
§Examples
use orx_parallel::*;
// parallel computation generic over parallel runner; and hence, the thread pool
fn run_with_runner<R: ParallelRunner>(runner: R, input: &[usize]) -> Vec<String> {
input
.par()
.with_runner(runner)
.flat_map(|x| [*x, 2 * x, x / 7])
.map(|x| x.to_string())
.collect()
}
let vec: Vec<_> = (0..42).collect();
let input = vec.as_slice();
// runs sequentially on the main thread
let runner = RunnerWithPool::from(SequentialPool);
let expected = run_with_runner(runner, input);
// uses native threads
let runner = RunnerWithPool::from(StdDefaultPool::default());
let result = run_with_runner(runner, input);
assert_eq!(&expected, &result);
// uses rayon-core ThreadPool with 8 threads
#[cfg(feature = "rayon-core")]
{
let pool = rayon_core::ThreadPoolBuilder::new()
.num_threads(8)
.build()
.unwrap();
let result = run_with_runner(RunnerWithPool::from(&pool), input);
assert_eq!(&expected, &result);
}
// uses scoped-pool Pool with 8 threads
#[cfg(feature = "scoped-pool")]
{
let pool = scoped_pool::Pool::new(8);
let result = run_with_runner(RunnerWithPool::from(&pool), input);
assert_eq!(&expected, &result);
}
// uses scoped_threadpool Pool with 8 threads
#[cfg(feature = "scoped_threadpool")]
{
let mut pool = scoped_threadpool::Pool::new(8);
let result = run_with_runner(RunnerWithPool::from(&mut pool), input); // requires &mut pool
assert_eq!(&expected, &result);
}
// uses yastl Pool wrapped as YastlPool with 8 threads
#[cfg(feature = "yastl")]
{
let pool = YastlPool::new(8);
let result = run_with_runner(RunnerWithPool::from(&pool), input);
assert_eq!(&expected, &result);
}
// uses pond Pool wrapped as PondPool with 8 threads
#[cfg(feature = "pond")]
{
let mut pool = PondPool::new_threads_unbounded(8);
let result = run_with_runner(RunnerWithPool::from(&mut pool), input); // requires &mut pool
assert_eq!(&expected, &result);
}
// uses poolite Pool with 8 threads
#[cfg(feature = "poolite")]
{
let pool = poolite::Pool::with_builder(poolite::Builder::new().min(8).max(8)).unwrap();
let result = run_with_runner(RunnerWithPool::from(&pool), input);
assert_eq!(&expected, &result);
}
Implementations§
Source§impl<P, R> RunnerWithPool<P, R>where
P: ParThreadPool,
R: ParallelExecutor,
impl<P, R> RunnerWithPool<P, R>where
P: ParThreadPool,
R: ParallelExecutor,
Sourcepub fn into_inner_pool(self) -> P
pub fn into_inner_pool(self) -> P
Converts the runner into the wrapped underlying pool.
Note that a RunnerWithPool
can always be created from owned pool
, but also from
&pool
in most cases,&mut pool
in others.
This function is only relevant when the runner is created from owned pool, in which case
into_inner_pool
can be used to get back ownership of the pool.
§Example
The following example demonstrates the use case for rayon-core thread pool; however, it holds for all thread pool implementations.
use orx_parallel::*;
let vec: Vec<_> = (0..42).collect();
let input = vec.as_slice();
#[cfg(feature = "rayon-core")]
{
let pool = rayon_core::ThreadPoolBuilder::new()
.num_threads(8)
.build()
.unwrap();
// create runner owning the pool
let mut runner = RunnerWithPool::from(pool);
// use runner, and hence the pool, in parallel computations
let sum = input.par().with_runner(&mut runner).sum();
let max = input.par().with_runner(&mut runner).max();
let txt: Vec<_> = input
.par()
.with_runner(&mut runner)
.map(|x| x.to_string())
.collect();
// get back ownership of the pool
let pool: rayon_core::ThreadPool = runner.into_inner_pool();
}
Sourcepub fn with_executor<Q: ParallelExecutor>(self) -> RunnerWithPool<P, Q>
pub fn with_executor<Q: ParallelExecutor>(self) -> RunnerWithPool<P, Q>
Converts the runner into one using the ParallelExecutor
Q
rather than R
.
Trait Implementations§
Source§impl<P, R> Default for RunnerWithPool<P, R>
impl<P, R> Default for RunnerWithPool<P, R>
Source§impl<P: ParThreadPool> From<P> for RunnerWithPool<P, DefaultExecutor>
impl<P: ParThreadPool> From<P> for RunnerWithPool<P, DefaultExecutor>
Source§impl<P, R> ParallelRunner for RunnerWithPool<P, R>where
P: ParThreadPool,
R: ParallelExecutor,
impl<P, R> ParallelRunner for RunnerWithPool<P, R>where
P: ParThreadPool,
R: ParallelExecutor,
Source§type ThreadPool = P
type ThreadPool = P
Thread pool responsible for providing threads to the parallel computation.
Source§fn thread_pool(&self) -> &Self::ThreadPool
fn thread_pool(&self) -> &Self::ThreadPool
Reference to the underlying thread pool.
Source§fn thread_pool_mut(&mut self) -> &mut Self::ThreadPool
fn thread_pool_mut(&mut self) -> &mut Self::ThreadPool
Mutable reference to the underlying thread pool.
Source§fn new_executor(
&self,
kind: ComputationKind,
params: Params,
initial_input_len: Option<usize>,
) -> Self::Executor
fn new_executor( &self, kind: ComputationKind, params: Params, initial_input_len: Option<usize>, ) -> Self::Executor
Creates a new parallel executor for a parallel computation.
Source§fn run_all<I, F>(
&mut self,
params: Params,
iter: I,
kind: ComputationKind,
thread_do: F,
) -> NumSpawnedwhere
I: ConcurrentIter,
F: Fn(NumSpawned, &I, &<<Self as ParallelRunner>::Executor as ParallelExecutor>::SharedState, <<Self as ParallelRunner>::Executor as ParallelExecutor>::ThreadExecutor) + Sync,
fn run_all<I, F>(
&mut self,
params: Params,
iter: I,
kind: ComputationKind,
thread_do: F,
) -> NumSpawnedwhere
I: ConcurrentIter,
F: Fn(NumSpawned, &I, &<<Self as ParallelRunner>::Executor as ParallelExecutor>::SharedState, <<Self as ParallelRunner>::Executor as ParallelExecutor>::ThreadExecutor) + Sync,
Runs
thread_do
using threads provided by the thread pool.Source§fn map_all<F, I, M, T>(
&mut self,
params: Params,
iter: I,
kind: ComputationKind,
thread_map: M,
) -> (NumSpawned, Result<Vec<T>, F::Error>)where
F: Fallibility,
I: ConcurrentIter,
M: Fn(NumSpawned, &I, &<<Self as ParallelRunner>::Executor as ParallelExecutor>::SharedState, <<Self as ParallelRunner>::Executor as ParallelExecutor>::ThreadExecutor) -> Result<T, F::Error> + Sync,
T: Send,
F::Error: Send,
fn map_all<F, I, M, T>(
&mut self,
params: Params,
iter: I,
kind: ComputationKind,
thread_map: M,
) -> (NumSpawned, Result<Vec<T>, F::Error>)where
F: Fallibility,
I: ConcurrentIter,
M: Fn(NumSpawned, &I, &<<Self as ParallelRunner>::Executor as ParallelExecutor>::SharedState, <<Self as ParallelRunner>::Executor as ParallelExecutor>::ThreadExecutor) -> Result<T, F::Error> + Sync,
T: Send,
F::Error: Send,
Runs
thread_map
using threads provided by the thread pool.Source§fn map_infallible<I, M, T>(
&mut self,
params: Params,
iter: I,
kind: ComputationKind,
thread_map: M,
) -> (NumSpawned, Result<Vec<T>, Never>)where
I: ConcurrentIter,
M: Fn(NumSpawned, &I, &<<Self as ParallelRunner>::Executor as ParallelExecutor>::SharedState, <<Self as ParallelRunner>::Executor as ParallelExecutor>::ThreadExecutor) -> Result<T, Never> + Sync,
T: Send,
fn map_infallible<I, M, T>(
&mut self,
params: Params,
iter: I,
kind: ComputationKind,
thread_map: M,
) -> (NumSpawned, Result<Vec<T>, Never>)where
I: ConcurrentIter,
M: Fn(NumSpawned, &I, &<<Self as ParallelRunner>::Executor as ParallelExecutor>::SharedState, <<Self as ParallelRunner>::Executor as ParallelExecutor>::ThreadExecutor) -> Result<T, Never> + Sync,
T: Send,
Runs infallible
thread_map
using threads provided by the thread pool.Source§fn max_num_threads_for_computation(
&self,
params: Params,
iter_len: Option<usize>,
) -> NonZeroUsize
fn max_num_threads_for_computation( &self, params: Params, iter_len: Option<usize>, ) -> NonZeroUsize
Returns the maximum number of threads that can be used for the computation defined by
the
params
and input iter_len
.Auto Trait Implementations§
impl<P, R> Freeze for RunnerWithPool<P, R>where
P: Freeze,
impl<P, R> RefUnwindSafe for RunnerWithPool<P, R>where
P: RefUnwindSafe,
R: RefUnwindSafe,
impl<P, R> Send for RunnerWithPool<P, R>
impl<P, R> Sync for RunnerWithPool<P, R>where
P: Sync,
impl<P, R> Unpin for RunnerWithPool<P, R>
impl<P, R> UnwindSafe for RunnerWithPool<P, R>where
P: UnwindSafe,
R: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
Converts
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more