orx_parallel/runner/
par_runner.rs1use crate::parameters::Params;
2use crate::pools::{ThreadPool, max_num_threads_for_computation};
3#[cfg(feature = "std")]
4use crate::runner::runner_variants::WithDiagnostics;
5use orx_concurrent_iter::ConcurrentIter;
6
7pub trait ParRunner: Sized + Sync {
9 type Pool: ThreadPool;
11
12 type State: Send + Sync;
14
15 type ChunkState;
17
18 fn pool(&self) -> &Self::Pool;
22
23 fn pool_mut(&mut self) -> &mut Self::Pool;
25
26 fn do_spawn_new(spawned: usize, state: &Self::State) -> Option<usize>;
34
35 fn new_state(
37 &mut self,
38 params: Params,
39 max_num_threads: usize,
40 size_hint: (usize, Option<usize>),
41 ) -> Self::State;
42
43 fn configure_for_serialized_input(state: &mut Self::State, size_hint: (usize, Option<usize>));
45
46 fn begin_thread(state: &Self::State, th_idx: usize);
48
49 fn next_chunk_size(state: &Self::State, size_hint: (usize, Option<usize>)) -> usize;
52
53 fn begin_chunk(th_idx: usize, chunk_size: usize) -> Self::ChunkState;
55
56 fn complete_chunk(state: &Self::State, chunk_state: Self::ChunkState);
58
59 fn complete_thread(state: &Self::State, th_idx: usize);
61
62 fn complete_computation(state: Self::State);
64
65 #[cfg(feature = "std")]
69 fn with_diagnostics(self) -> WithDiagnostics<Self> {
70 WithDiagnostics::new(self)
71 }
72
73 fn nt_state(
80 &mut self,
81 params: Params,
82 is_source_serialized: bool,
83 size_hint: (usize, Option<usize>),
84 computation_max_nt: Option<usize>,
85 ) -> (usize, Self::State) {
86 let max_nt = max_num_threads_for_computation(self.pool(), params, size_hint);
87
88 let max_nt = match computation_max_nt {
89 Some(0) => 1,
90 Some(comp_nt) if comp_nt < max_nt => comp_nt,
91 _ => max_nt,
92 };
93
94 let mut state = self.new_state(params, max_nt, size_hint);
95 if is_source_serialized {
96 Self::configure_for_serialized_input(&mut state, size_hint);
97 }
98 (max_nt, state)
99 }
100
101 fn broadcast_stop<I: ConcurrentIter>(
103 iter: &I,
104 state: &Self::State,
105 chunk_state: Self::ChunkState,
106 ) {
107 iter.skip_to_end();
108 Self::complete_chunk(state, chunk_state);
109 }
110}
111
112impl<P: ParRunner> ParRunner for &mut P {
113 type Pool = P::Pool;
114
115 type State = P::State;
116
117 type ChunkState = P::ChunkState;
118
119 fn pool(&self) -> &Self::Pool {
120 <P as ParRunner>::pool(self)
121 }
122
123 fn pool_mut(&mut self) -> &mut Self::Pool {
124 <P as ParRunner>::pool_mut(self)
125 }
126
127 fn do_spawn_new(spawned: usize, state: &Self::State) -> Option<usize> {
128 <P as ParRunner>::do_spawn_new(spawned, state)
129 }
130
131 fn new_state(
132 &mut self,
133 params: Params,
134 max_num_threads: usize,
135 size_hint: (usize, Option<usize>),
136 ) -> Self::State {
137 <P as ParRunner>::new_state(self, params, max_num_threads, size_hint)
138 }
139
140 fn begin_thread(state: &Self::State, th_idx: usize) {
141 <P as ParRunner>::begin_thread(state, th_idx);
142 }
143
144 fn next_chunk_size(state: &Self::State, size_hint: (usize, Option<usize>)) -> usize {
145 <P as ParRunner>::next_chunk_size(state, size_hint)
146 }
147
148 fn begin_chunk(th_idx: usize, chunk_size: usize) -> Self::ChunkState {
149 <P as ParRunner>::begin_chunk(th_idx, chunk_size)
150 }
151
152 fn complete_chunk(state: &Self::State, chunk_state: Self::ChunkState) {
153 <P as ParRunner>::complete_chunk(state, chunk_state);
154 }
155
156 fn complete_thread(state: &Self::State, th_idx: usize) {
157 <P as ParRunner>::complete_thread(state, th_idx);
158 }
159
160 fn complete_computation(state: Self::State) {
161 <P as ParRunner>::complete_computation(state);
162 }
163
164 fn configure_for_serialized_input(state: &mut Self::State, size_hint: (usize, Option<usize>)) {
165 <P as ParRunner>::configure_for_serialized_input(state, size_hint);
166 }
167}