7
7
******************************************************************************/
8
8
9
9
#include " common/ExecutionContext.h"
10
- #include " common/Logger.h"
11
10
#include " cudaq/qis/execution_manager.h"
12
11
13
- #include < complex>
14
- #include < functional>
15
- #include < map>
16
- #include < queue>
17
- #include < stack>
18
-
19
12
namespace cudaq {
20
13
21
14
// / @brief The `BasicExecutionManager` provides a common base class for
@@ -41,30 +34,25 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
41
34
std::vector<cudaq::QuditInfo>, spin_op>;
42
35
43
36
// / @brief `typedef` for a queue of instructions
44
- using InstructionQueue = std::queue <Instruction>;
37
+ using InstructionQueue = std::vector <Instruction>;
45
38
46
- // / @brief The current execution context, e.g. sampling
47
- // / or observation
39
+ // / @brief The current execution context, e.g. sampling or observation
48
40
cudaq::ExecutionContext *executionContext = nullptr ;
49
41
50
- // / @brief Store qudits for delayed deletion under
51
- // / certain execution contexts
42
+ // / @brief Store qudits for delayed deletion under certain execution contexts
52
43
std::vector<QuditInfo> contextQuditIdsForDeletion;
53
44
54
45
// / @brief The current queue of operations to execute
55
46
InstructionQueue instructionQueue;
56
47
57
- // / @brief When adjoint operations are requested
58
- // / we can store them here for delayed execution
59
- std::stack <InstructionQueue> adjointQueueStack;
48
+ // / @brief When adjoint operations are requested we can store them here for
49
+ // / delayed execution
50
+ std::vector <InstructionQueue> adjointQueueStack;
60
51
61
- // / @brief When we are in a control region, we
62
- // / need to store extra control qudit ids.
52
+ // / @brief When we are in a control region, we need to store extra control
53
+ // / qudit ids.
63
54
std::vector<std::size_t > extraControlIds;
64
55
65
- // / @brief Flag to indicate we are in an adjoint region
66
- bool inAdjointRegion = false ;
67
-
68
56
// / @brief Subtype-specific qudit allocation method
69
57
virtual void allocateQudit (const QuditInfo &q) = 0;
70
58
@@ -78,16 +66,15 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
78
66
// / all qudits in the vector.
79
67
virtual void deallocateQudits (const std::vector<QuditInfo> &qudits) = 0;
80
68
81
- // / @brief Subtype-specific handler for when
82
- // the execution context changes
69
+ // / @brief Subtype-specific handler for when the execution context changes
83
70
virtual void handleExecutionContextChanged () = 0;
84
71
85
- // / @brief Subtype-specific handler for when the
86
- // / current execution context has ended.
72
+ // / @brief Subtype-specific handler for when the current execution context has
73
+ // / ended.
87
74
virtual void handleExecutionContextEnded () = 0;
88
75
89
- // / @brief Subtype-specific method for affecting the
90
- // / execution of a queued instruction.
76
+ // / @brief Subtype-specific method for affecting the execution of a queued
77
+ // / instruction.
91
78
virtual void executeInstruction (const Instruction &inst) = 0;
92
79
93
80
// / @brief Subtype-specific method for performing qudit measurement.
@@ -97,7 +84,6 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
97
84
virtual void measureSpinOp (const cudaq::spin_op &op) = 0;
98
85
99
86
// / @brief Subtype-specific method for performing qudit reset.
100
- // / @param q Qudit to reset
101
87
virtual void resetQudit (const QuditInfo &q) = 0;
102
88
103
89
public:
@@ -107,9 +93,7 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
107
93
void setExecutionContext (cudaq::ExecutionContext *_ctx) override {
108
94
executionContext = _ctx;
109
95
handleExecutionContextChanged ();
110
- while (!instructionQueue.empty ()) {
111
- instructionQueue.pop ();
112
- }
96
+ instructionQueue.clear ();
113
97
}
114
98
115
99
void resetExecutionContext () override {
@@ -161,44 +145,30 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
161
145
contextQuditIdsForDeletion.push_back (qid);
162
146
}
163
147
164
- void startAdjointRegion () override { adjointQueueStack.emplace (); }
148
+ void startAdjointRegion () override { adjointQueueStack.emplace_back (); }
165
149
166
150
void endAdjointRegion () override {
167
- // Get the top queue and remove it
168
- auto adjointQueue = adjointQueueStack.top ();
169
- adjointQueueStack.pop ();
170
-
171
- // Reverse it
172
- [](InstructionQueue &q) {
173
- std::stack<Instruction> s;
174
- while (!q.empty ()) {
175
- s.push (q.front ());
176
- q.pop ();
177
- }
178
- while (!s.empty ()) {
179
- q.push (s.top ());
180
- s.pop ();
181
- }
182
- }(adjointQueue);
151
+ assert (!adjointQueueStack.empty () && " There must be at least one queue" );
183
152
184
- while (!adjointQueue.empty ()) {
185
- auto front = adjointQueue.front ();
186
- adjointQueue.pop ();
187
- if (adjointQueueStack.empty ()) {
188
- instructionQueue.push (front);
189
- } else {
190
- adjointQueueStack.top ().push (front);
191
- }
192
- }
153
+ auto adjointQueue = std::move (adjointQueueStack.back ());
154
+ adjointQueueStack.pop_back ();
155
+
156
+ // Select the queue to which these instructions will be added.
157
+ InstructionQueue *queue = adjointQueueStack.empty ()
158
+ ? &instructionQueue
159
+ : &(adjointQueueStack.back ());
160
+
161
+ std::reverse (adjointQueue.begin (), adjointQueue.end ());
162
+ for (auto &instruction : adjointQueue)
163
+ queue->push_back (instruction);
193
164
}
194
165
195
166
void startCtrlRegion (const std::vector<std::size_t > &controls) override {
196
- for (auto & c : controls)
167
+ for (auto c : controls)
197
168
extraControlIds.push_back (c);
198
169
}
199
170
200
171
void endCtrlRegion (const std::size_t n_controls) override {
201
- // extra_control_qubits.erase(end - n_controls, end);
202
172
extraControlIds.resize (extraControlIds.size () - n_controls);
203
173
}
204
174
@@ -239,20 +209,18 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
239
209
240
210
if (!adjointQueueStack.empty ()) {
241
211
// Add to the adjoint instruction queue
242
- adjointQueueStack.top ().emplace ( std::make_tuple (
243
- mutable_name, mutable_params, mutable_controls, mutable_targets, op)) ;
212
+ adjointQueueStack.back ().emplace_back (
213
+ mutable_name, mutable_params, mutable_controls, mutable_targets, op);
244
214
return ;
245
215
}
246
216
247
217
// Add to the instruction queue
248
- instructionQueue.emplace (std::make_tuple (std::move (mutable_name),
249
- mutable_params, mutable_controls,
250
- mutable_targets, op));
218
+ instructionQueue.emplace_back (std::move (mutable_name), mutable_params,
219
+ mutable_controls, mutable_targets, op);
251
220
}
252
221
253
222
void synchronize () override {
254
- while (!instructionQueue.empty ()) {
255
- auto instruction = instructionQueue.front ();
223
+ for (auto &instruction : instructionQueue) {
256
224
if (isInTracerMode ()) {
257
225
auto [gateName, params, controls, targets, op] = instruction;
258
226
std::vector<std::size_t > controlIds;
@@ -264,8 +232,8 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
264
232
} else {
265
233
executeInstruction (instruction);
266
234
}
267
- instructionQueue.pop ();
268
235
}
236
+ instructionQueue.clear ();
269
237
}
270
238
271
239
int measure (const cudaq::QuditInfo &target) override {
0 commit comments