Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
NetworkJob.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#ifndef _NETWORK_JOB_H
13#define _NETWORK_JOB_H
14
15#include "../Types.h"
17
18namespace Network {
19
20template <typename Time = Types::time_type> class ExecuteJob {
21public:
23
24 ExecuteJob() = delete;
25
26 explicit ExecuteJob(const std::shared_ptr<Circuits::Circuit<Time>> &c,
27 ExecuteResults &r, size_t cnt, size_t nq, size_t nc,
28 size_t ncr, Simulators::SimulatorType t,
29 Simulators::SimulationType m, std::mutex &mut)
30 : dcirc(c), res(r), curCnt(cnt), nrQubits(nq), nrCbits(nc),
31 nrResultCbits(ncr), simType(t), method(m), resultsMutex(mut) {}
32
33 void DoWork() {
34 if (curCnt == 0)
35 return;
36
38 state.AllocateBits(nrCbits);
39
40 const bool hasMeasurementsOnlyAtEnd = !dcirc->HasOpsAfterMeasurements();
41 const bool optimiseMultipleShots = optimiseMultipleShotsExecution;
42 const bool specialOptimizationForStatevector =
43 optimiseMultipleShots &&
45 hasMeasurementsOnlyAtEnd;
46 const bool specialOptimizationForMPS =
47 optimiseMultipleShots &&
49 hasMeasurementsOnlyAtEnd;
50
51 if (!optSim) {
53 if (!optSim)
54 return;
55
56 if (!maxBondDim.empty())
57 optSim->Configure("matrix_product_state_max_bond_dimension",
58 maxBondDim.c_str());
59 if (!singularValueThreshold.empty())
60 optSim->Configure("matrix_product_state_truncation_threshold",
62 if (!mpsSample.empty())
63 optSim->Configure("mps_sample_measure_algorithm", mpsSample.c_str());
64
65 optSim->AllocateQubits(nrQubits);
66 optSim->Initialize();
67
68 if (optimiseMultipleShots) {
69 executedGates = dcirc->ExecuteNonMeasurements(optSim, state);
70
71 if (!specialOptimizationForStatevector && !specialOptimizationForMPS)
72 optSim->SaveState();
73 }
74 }
75
76 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
77
78 const std::vector<bool> executed = std::move(executedGates);
79
80 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
81 measurementsOp = dcirc->GetLastMeasurements(
82 executed, optSim->GetType() == Simulators::SimulatorType::kQiskitAer);
83
84 const auto &qbits = measurementsOp->GetQubits();
85 if (qbits.empty()) {
86 auto bits = state.GetAllBits();
87 bits.resize(nrResultCbits, false);
88
89 const std::lock_guard lock(resultsMutex);
90 res[bits] += curCnt;
91
92 return;
93 }
94 }
95
96 ExecuteResults localRes;
97
98 if (optimiseMultipleShots &&
99 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
100 const auto &qbits = measurementsOp->GetQubits();
101
102 const auto sampleres = optSim->SampleCounts(qbits, curCnt);
103
104 for (const auto &[mstate, cnt] : sampleres) {
105 measurementsOp->SetStateFromSample(mstate, state);
106
107 auto bits = state.GetAllBits();
108 bits.resize(nrResultCbits, false);
109
110 localRes[bits] += cnt;
111
112 state.Reset();
113 }
114
115 const std::lock_guard lock(resultsMutex);
116 for (const auto &r : localRes)
117 res[r.first] += r.second;
118
119 return;
120 }
121
122 const auto curCnt1 = curCnt > 0 ? curCnt - 1 : 0;
123 for (size_t i = 0; i < curCnt; ++i) {
124 if (optimiseMultipleShots) {
125 optSim->RestoreState();
126 dcirc->ExecuteMeasurements(optSim, state, executed);
127 } else {
128 dcirc->Execute(optSim, state);
129 if (i < curCnt1)
130 optSim->Reset();
131 }
132
133 auto bits = state.GetAllBits();
134 bits.resize(nrResultCbits, false);
135
136 ++localRes[bits];
137
138 state.Reset();
139 }
140
141 const std::lock_guard lock(resultsMutex);
142 for (const auto &r : localRes)
143 res[r.first] += r.second;
144 }
145
147 if (curCnt == 0)
148 return;
149
151 state.AllocateBits(nrCbits);
152
153 const bool hasMeasurementsOnlyAtEnd = !dcirc->HasOpsAfterMeasurements();
154 const bool optimiseMultipleShots = optimiseMultipleShotsExecution;
155 const bool specialOptimizationForStatevector =
156 optimiseMultipleShots &&
158 hasMeasurementsOnlyAtEnd;
159 const bool specialOptimizationForMPS =
160 optimiseMultipleShots &&
162 hasMeasurementsOnlyAtEnd;
163
164 if (optSim) {
165 optSim->SetMultithreading(true);
166
167 if (optSim->GetNumberOfQubits() != nrQubits) {
168 optSim->Clear();
169
170 if (!maxBondDim.empty())
171 optSim->Configure("matrix_product_state_max_bond_dimension",
172 maxBondDim.c_str());
173 if (!singularValueThreshold.empty())
174 optSim->Configure("matrix_product_state_truncation_threshold",
175 singularValueThreshold.c_str());
176 if (!mpsSample.empty())
177 optSim->Configure("mps_sample_measure_algorithm", mpsSample.c_str());
178
179 optSim->AllocateQubits(nrQubits);
180 optSim->Initialize();
181
182 if (optimiseMultipleShots) {
183 executedGates = dcirc->ExecuteNonMeasurements(optSim, state);
184
185 if (!specialOptimizationForStatevector && !specialOptimizationForMPS)
186 optSim->SaveState();
187 }
188 }
189 } else {
191 if (!optSim)
192 return;
193
194 optSim->SetMultithreading(true);
195
196 if (!maxBondDim.empty())
197 optSim->Configure("matrix_product_state_max_bond_dimension",
198 maxBondDim.c_str());
199 if (!singularValueThreshold.empty())
200 optSim->Configure("matrix_product_state_truncation_threshold",
201 singularValueThreshold.c_str());
202 if (!mpsSample.empty())
203 optSim->Configure("mps_sample_measure_algorithm", mpsSample.c_str());
204
205 optSim->AllocateQubits(nrQubits);
206 optSim->Initialize();
207
208 if (optimiseMultipleShots) {
209 executedGates = dcirc->ExecuteNonMeasurements(optSim, state);
210
211 if (!specialOptimizationForStatevector && !specialOptimizationForMPS)
212 optSim->SaveState();
213 }
214 }
215
216 std::shared_ptr<Circuits::MeasurementOperation<Time>> measurementsOp;
217
218 const std::vector<bool> executed = std::move(executedGates);
219
220 if (optimiseMultipleShots && hasMeasurementsOnlyAtEnd) {
221 measurementsOp = dcirc->GetLastMeasurements(
222 executed, optSim->GetType() == Simulators::SimulatorType::kQiskitAer);
223
224 const auto &qbits = measurementsOp->GetQubits();
225 if (qbits.empty()) {
226 auto bits = state.GetAllBits();
227 bits.resize(nrResultCbits, false);
228
229 res[bits] += curCnt;
230
231 return;
232 }
233 }
234
235 if (optimiseMultipleShots &&
236 (specialOptimizationForStatevector || hasMeasurementsOnlyAtEnd)) {
237 const auto &qbits = measurementsOp->GetQubits();
238
239 const auto sampleres = optSim->SampleCounts(qbits, curCnt);
240
241 for (const auto &[mstate, cnt] : sampleres) {
242 measurementsOp->SetStateFromSample(mstate, state);
243
244 auto bits = state.GetAllBits();
245 bits.resize(nrResultCbits, false);
246
247 res[bits] += cnt;
248
249 state.Reset();
250 }
251
252 return;
253 }
254
255 const auto curCnt1 = curCnt > 0 ? curCnt - 1 : 0;
256 for (size_t i = 0; i < curCnt; ++i) {
257 if (optimiseMultipleShots) {
258 optSim->RestoreState();
259 dcirc->ExecuteMeasurements(optSim, state, executed);
260 } else {
261 dcirc->Execute(optSim, state);
262 if (i < curCnt1)
263 optSim->Reset(); // leave the simulator state for the last iteration
264 }
265
266 auto bits = state.GetAllBits();
267 bits.resize(nrResultCbits, false);
268
269 ++res[bits];
270
271 state.Reset();
272 }
273 }
274
276 size_t curCnt) {
277 return curCnt > 1;
278 }
279
280 size_t GetJobCount() const { return curCnt; }
281
282 const std::shared_ptr<Circuits::Circuit<Time>> dcirc;
284 const size_t curCnt;
285 const size_t nrQubits;
286 const size_t nrCbits;
287 const size_t nrResultCbits;
288
291 std::mutex &resultsMutex;
292
294 std::shared_ptr<Simulators::ISimulator> optSim;
295 std::vector<bool> executedGates;
296
297 // only fill them if passing null simulator
298 std::string maxBondDim;
300 std::string mpsSample;
301};
302
303} // namespace Network
304
305#endif // ! _NETWORK_JOB_H
Circuit class for holding the sequence of operations.
Definition Circuit.h:45
std::unordered_map< std::vector< bool >, size_t > ExecuteResults
The results of the execution of the circuit.
Definition Circuit.h:47
The state class that stores the classical state of a quantum circuit execution.
Definition Operations.h:62
void Reset(bool value=false)
Set the classical bits with the specified value.
Definition Operations.h:246
const std::vector< bool > & GetAllBits() const
Get the classical bits.
Definition Operations.h:215
void AllocateBits(size_t numBits)
Allocate more bits.
Definition Operations.h:159
ExecuteResults & res
Definition NetworkJob.h:283
bool optimiseMultipleShotsExecution
Definition NetworkJob.h:293
static bool IsOptimisableForMultipleShots(Simulators::SimulatorType t, size_t curCnt)
Definition NetworkJob.h:275
const Simulators::SimulatorType simType
Definition NetworkJob.h:289
std::string maxBondDim
Definition NetworkJob.h:298
const size_t curCnt
Definition NetworkJob.h:284
std::vector< bool > executedGates
Definition NetworkJob.h:295
typename Circuits::Circuit< Time >::ExecuteResults ExecuteResults
Definition NetworkJob.h:22
const size_t nrResultCbits
Definition NetworkJob.h:287
const size_t nrCbits
Definition NetworkJob.h:286
ExecuteJob(const std::shared_ptr< Circuits::Circuit< Time > > &c, ExecuteResults &r, size_t cnt, size_t nq, size_t nc, size_t ncr, Simulators::SimulatorType t, Simulators::SimulationType m, std::mutex &mut)
Definition NetworkJob.h:26
const std::shared_ptr< Circuits::Circuit< Time > > dcirc
Definition NetworkJob.h:282
std::shared_ptr< Simulators::ISimulator > optSim
Definition NetworkJob.h:294
std::mutex & resultsMutex
Definition NetworkJob.h:291
const size_t nrQubits
Definition NetworkJob.h:285
std::string mpsSample
Definition NetworkJob.h:300
const Simulators::SimulationType method
Definition NetworkJob.h:290
std::string singularValueThreshold
Definition NetworkJob.h:299
size_t GetJobCount() const
Definition NetworkJob.h:280
static std::shared_ptr< ISimulator > CreateSimulator(SimulatorType t=SimulatorType::kQCSim, SimulationType method=SimulationType::kMatrixProductState)
Create a quantum computing simulator.
Definition Factory.cpp:78
SimulationType
The type of simulation.
Definition State.h:82
@ kStatevector
statevector simulation type
Definition State.h:83
@ kMatrixProductState
matrix product state simulation type
Definition State.h:84
SimulatorType
The type of simulator.
Definition State.h:63
@ kQiskitAer
qiskit aer simulator type
Definition State.h:65