Skip to main content

quantrs2_sim/scirs2_integration/
scirs2parallelcontext_traits.rs

1//! # SciRS2ParallelContext - Trait Implementations
2//!
3//! This module contains trait implementations for `SciRS2ParallelContext`.
4//!
5//! ## Implemented Traits
6//!
7//! - `Default`
8//!
9//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
10
11use scirs2_core::parallel_ops::{
12    current_num_threads, IndexedParallelIterator, ParallelIterator, ThreadPool, ThreadPoolBuilder,
13};
14use scirs2_core::random::prelude::*;
15use std::sync::{Arc, OnceLock};
16
17use super::types::SciRS2ParallelContext;
18
19/// Process-wide worker pool backing every [`SciRS2ParallelContext`].
20static SHARED_THREAD_POOL: OnceLock<Arc<ThreadPool>> = OnceLock::new();
21
22/// Returns the shared worker pool, building it on first use.
23///
24/// A `SciRS2ParallelContext` is constructed by every `SciRS2Backend::new()`, and thus by
25/// every `StateVectorSimulator::new()`. Building one rayon pool per context spawns
26/// `num_threads` OS threads each time, which dominates the runtime of any workload that
27/// creates a simulator in a loop (parameter-shift gradients create one per evaluation).
28/// One pool for the process keeps that cost at zero after the first call.
29pub fn shared_thread_pool() -> Arc<ThreadPool> {
30    Arc::clone(SHARED_THREAD_POOL.get_or_init(|| {
31        let pool = ThreadPoolBuilder::new()
32            .num_threads(current_num_threads())
33            .build()
34            .unwrap_or_else(|_| {
35                ThreadPoolBuilder::new()
36                    .build()
37                    .expect("fallback thread pool creation should succeed")
38            });
39        Arc::new(pool)
40    }))
41}
42
43impl Default for SciRS2ParallelContext {
44    fn default() -> Self {
45        let thread_pool = shared_thread_pool();
46        Self {
47            num_threads: thread_pool.current_num_threads(),
48            thread_pool,
49            numa_aware: true,
50        }
51    }
52}