Skip to main content

quantrs2_sim/automatic_parallelization/
autoparallelengine_execute_parallel_tasks_group.rs

1//! # AutoParallelEngine - execute_parallel_tasks_group Methods
2//!
3//! This module contains method implementations for `AutoParallelEngine`.
4//!
5//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
6
7use quantrs2_core::{
8    error::{QuantRS2Error, QuantRS2Result},
9    gate::GateOp,
10    qubit::QubitId,
11};
12use scirs2_core::parallel_ops::{current_num_threads, IndexedParallelIterator, ParallelIterator};
13use scirs2_core::Complex64;
14use std::sync::{Arc, Barrier, Mutex, RwLock};
15
16use super::types::ParallelTask;
17
18use super::autoparallelengine_type::AutoParallelEngine;
19
20impl AutoParallelEngine {
21    /// Execute parallel tasks with proper synchronization
22    pub(super) fn execute_parallel_tasks(
23        &self,
24        tasks: &[ParallelTask],
25        shared_state: Arc<RwLock<Vec<Complex64>>>,
26        results: Arc<Mutex<Vec<Complex64>>>,
27        barrier: Arc<Barrier>,
28    ) -> QuantRS2Result<()> {
29        use scirs2_core::parallel_ops::{parallel_map, IndexedParallelIterator};
30        let _ = parallel_map(tasks, |task| {
31            barrier.wait();
32            let mut state = shared_state
33                .write()
34                .expect("Failed to acquire write lock on shared state");
35            for gate in &task.gates {
36                let qubits = gate.qubits();
37                match qubits.len() {
38                    1 => {
39                        Self::apply_single_qubit_gate_to_state(
40                            &mut state,
41                            gate.as_ref(),
42                            qubits[0].0 as usize,
43                        );
44                    }
45                    2 => {
46                        Self::apply_two_qubit_gate_to_state(
47                            &mut state,
48                            gate.as_ref(),
49                            qubits[0].0 as usize,
50                            qubits[1].0 as usize,
51                        );
52                    }
53                    _ => {
54                        eprintln!(
55                            "Warning: {}-qubit gates not optimized for parallel execution",
56                            qubits.len()
57                        );
58                    }
59                }
60            }
61            barrier.wait();
62        });
63        let final_state = shared_state
64            .read()
65            .expect("Failed to acquire read lock on shared state");
66        let mut result_vec = results.lock().expect("Failed to acquire lock on results");
67        result_vec.clone_from(&final_state);
68        Ok(())
69    }
70    /// Apply a single-qubit gate to a state vector
71    pub(super) fn apply_single_qubit_gate_to_state(
72        state: &mut [Complex64],
73        gate: &dyn GateOp,
74        qubit: usize,
75    ) {
76        let num_qubits = (state.len() as f64).log2() as usize;
77        let stride = 1 << qubit;
78        for base in 0..state.len() {
79            if (base & stride) == 0 {
80                let idx0 = base;
81                let idx1 = base | stride;
82                let amp0 = state[idx0];
83                let amp1 = state[idx1];
84                state[idx0] = amp0;
85                state[idx1] = amp1;
86            }
87        }
88    }
89    /// Apply a two-qubit gate to a state vector
90    pub(super) fn apply_two_qubit_gate_to_state(
91        state: &mut [Complex64],
92        gate: &dyn GateOp,
93        qubit1: usize,
94        qubit2: usize,
95    ) {
96        let num_qubits = (state.len() as f64).log2() as usize;
97        let stride1 = 1 << qubit1;
98        let stride2 = 1 << qubit2;
99        for base in 0..state.len() {
100            if (base & stride1) == 0 && (base & stride2) == 0 {
101                let idx00 = base;
102                let idx01 = base | stride1;
103                let idx10 = base | stride2;
104                let idx11 = base | stride1 | stride2;
105                let amp00 = state[idx00];
106                let amp01 = state[idx01];
107                let amp10 = state[idx10];
108                let amp11 = state[idx11];
109                state[idx00] = amp00;
110                state[idx01] = amp01;
111                state[idx10] = amp10;
112                state[idx11] = amp11;
113            }
114        }
115    }
116}