wings-quantum 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ """Circuit evaluators for different backends."""
2
+
3
+ from .cpu import ThreadSafeCircuitEvaluator
4
+ from .custatevec import (
5
+ BatchedCuStateVecEvaluator,
6
+ CuStateVecEvaluator,
7
+ CuStateVecSimulator,
8
+ MultiGPUBatchEvaluator,
9
+ )
10
+ from .gpu import GPUCircuitEvaluator
11
+
12
+ __all__ = [
13
+ "ThreadSafeCircuitEvaluator",
14
+ "GPUCircuitEvaluator",
15
+ "CuStateVecSimulator",
16
+ "CuStateVecEvaluator",
17
+ "BatchedCuStateVecEvaluator",
18
+ "MultiGPUBatchEvaluator",
19
+ ]
@@ -0,0 +1,72 @@
1
+ """Thread-safe CPU circuit evaluator."""
2
+
3
+ import threading
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ import numpy as np
7
+ from qiskit import QuantumCircuit
8
+ from qiskit.circuit import ParameterVector
9
+ from qiskit.quantum_info import Statevector
10
+
11
+ from ..ansatz import get_full_variational_quantum_circuit
12
+ from ..types import ComplexArray, ParameterArray
13
+
14
+ if TYPE_CHECKING:
15
+ from ..config import OptimizerConfig
16
+
17
+ __all__ = ["ThreadSafeCircuitEvaluator"]
18
+
19
+
20
+ class ThreadSafeCircuitEvaluator:
21
+ """
22
+ Thread-safe circuit evaluation for parallel gradient computation.
23
+
24
+ Each thread gets its own circuit copy to avoid race conditions.
25
+ """
26
+
27
+ def __init__(self, config: "OptimizerConfig", target: ComplexArray) -> None:
28
+ self.config: OptimizerConfig = config
29
+ self.target: ComplexArray = target
30
+ self._target_conj: ComplexArray = np.conj(target)
31
+ self.n_params: int = config.n_params
32
+
33
+ # Thread-local storage for circuit copies
34
+ self._local = threading.local()
35
+
36
+ def _get_circuit(self) -> tuple[QuantumCircuit, list[Any]]:
37
+ """Get or create thread-local circuit"""
38
+ if not hasattr(self._local, "circuit"):
39
+ # Create fresh circuit for this thread
40
+ from qiskit import transpile
41
+
42
+ param_vector = ParameterVector("theta", self.n_params)
43
+ circuit = get_full_variational_quantum_circuit(
44
+ thetas=param_vector,
45
+ D2=self.config.n_qubits,
46
+ qubits_num=self.config.n_qubits,
47
+ input_state=None,
48
+ )
49
+ self._local.circuit = transpile(
50
+ circuit, basis_gates=["ry", "cx", "x"], optimization_level=1
51
+ )
52
+ self._local.param_vector = param_vector
53
+ self._local.param_list = list(param_vector)
54
+
55
+ return self._local.circuit, self._local.param_list
56
+
57
+ def get_statevector(self, params: ParameterArray) -> ComplexArray:
58
+ """Thread-safe statevector computation"""
59
+ circuit, param_list = self._get_circuit()
60
+ bound_circuit = circuit.assign_parameters(dict(zip(param_list, params)))
61
+ return Statevector(bound_circuit).data
62
+
63
+ def compute_fidelity(self, params: ParameterArray) -> float:
64
+ """Thread-safe fidelity computation"""
65
+ psi = self.get_statevector(params)
66
+ overlap = np.dot(self._target_conj, psi)
67
+ return overlap.real**2 + overlap.imag**2
68
+
69
+ def compute_fidelity_from_psi(self, psi: ComplexArray) -> float:
70
+ """Compute fidelity from statevector"""
71
+ overlap = np.dot(self._target_conj, psi)
72
+ return overlap.real**2 + overlap.imag**2