1use crate::{
6 error::Result,
7 execution::{Capability, LiveExecution, QuantumExecution},
8 ir::qubit::LogicalQubit,
9 prelude::Hamiltonian,
10};
11
12use super::{ExecutionProtocol, Process};
13
14impl Process {
15 fn live_execution_or_none<F, T>(&mut self, call: F) -> Option<T>
16 where
17 F: Fn(&mut Box<dyn LiveExecution>) -> T,
18 {
19 if let Some(QuantumExecution::Live(execution)) = self.quantum_execution.as_mut() {
20 Some(call(execution))
21 } else {
22 None
23 }
24 }
25
26 pub fn measure(&mut self, qubits: &[LogicalQubit]) -> Result<usize> {
27 self.non_gate_checks(Some(qubits), self.features.measure)?;
28 self.execute_gate_queue(0);
29
30 let index = self.measurements.len();
31
32 self.logical_circuit.measure(qubits, index);
33
34 let result = self.live_execution_or_none(|execution| execution.measure(qubits));
35 self.measurements.push(result);
36
37 for qubit in qubits {
38 self.valid_qubit.insert(*qubit, true);
39 }
40
41 if !matches!(
42 self.execution_target.execution_protocol,
43 ExecutionProtocol::ManagedByTarget {
44 measure: Capability::Advanced,
45 ..
46 }
47 ) {
48 for qubit in qubits {
49 self.valid_qubit.insert(*qubit, false);
50 }
51 }
52 Ok(index)
53 }
54
55 pub fn sample(&mut self, qubits: &[LogicalQubit], shots: usize) -> Result<usize> {
56 self.non_gate_checks(Some(qubits), self.features.sample)?;
57 self.execute_gate_queue(0);
58
59 let index = self.samples.len();
60
61 self.logical_circuit.sample(qubits, shots, index);
62
63 let result = self.live_execution_or_none(|execution| execution.sample(qubits, shots));
64 self.samples.push(result);
65
66 if self.execute_after_sample() {
67 self.execute()?
68 }
69
70 Ok(index)
71 }
72
73 pub fn exp_value(&mut self, hamiltonian: Hamiltonian<LogicalQubit>) -> Result<usize> {
74 let qubits = hamiltonian.qubits().cloned().collect::<Vec<_>>();
75 self.non_gate_checks(Some(&qubits), self.features.exp_value)?;
76 self.execute_gate_queue(0);
77
78 let index = self.exp_values.len();
79
80 let result = self.live_execution_or_none(|execution| execution.exp_value(&hamiltonian));
81 self.exp_values.push(result);
82
83 self.logical_circuit.exp_value(hamiltonian, index);
84
85 if self.execute_after_exp_value() {
86 self.execute()?;
87 }
88
89 Ok(index)
90 }
91
92 pub fn dump(&mut self, qubits: &[LogicalQubit]) -> Result<usize> {
93 self.non_gate_checks(Some(qubits), self.features.dump)?;
94 self.execute_gate_queue(0);
95
96 let index = self.dumps.len();
97
98 self.logical_circuit.dump(qubits, index);
99
100 let result = self.live_execution_or_none(|execution| execution.dump(qubits));
101 self.dumps.push(result);
102
103 if self.execute_after_dump() {
104 self.execute()?;
105 }
106
107 Ok(index)
108 }
109}