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}