Maestro 0.2.5
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
SimpleOps.h
Go to the documentation of this file.
1
13#pragma once
14
15#ifndef _SIMPLEOPS_H_
16#define _SIMPLEOPS_H_
17
18#include "Expr.h"
19
20namespace qasm {
21// something like this id[value] used for example by qreg and creg declarations
22// also when a qubit or cbit is referenced
24 public:
25 IndexedId() : index(0) {}
26 IndexedId(const std::string &id, int index) : id(id), index(index) {}
27
29
30 double Eval() const { return index; }
31
32 operator std::string() const {
33 return declType + " " + id + "[" + std::to_string(index) + "]";
34 }
35
36 std::string id;
37 int index;
38 int base = 0; // to be used when allocating the qubits/cbits in the circuit
39 std::string declType; // "qreg" or "creg" or "id"
40};
41
43 template <typename, typename>
44 struct result {
45 typedef IndexedId type;
46 };
47
48 template <typename ID, typename IND>
49 IndexedId operator()(const ID &id, IND index) const {
50 return IndexedId(id, index);
51 }
52};
53
54phx::function<MakeIndexedIdExpression> MakeIndexedId;
55
56using SimpleExpType = std::variant<double, int, std::string>;
57
58using ArgumentType = std::variant<std::string, IndexedId>;
59using MixedListType = std::vector<ArgumentType>;
60
61using SimpleGatecallType = boost::fusion::vector<std::string, MixedListType>;
63 boost::fusion::vector<std::string, std::vector<Expression>, MixedListType>;
64using GatecallType = std::variant<SimpleGatecallType, ExpGatecallType>;
65
67 boost::fusion::vector<std::vector<Expression>, ArgumentType>;
68using CXGateCallType = boost::fusion::vector<ArgumentType, ArgumentType>;
69
70using UopType = std::variant<UGateCallType, CXGateCallType, GatecallType>;
71
73 enum class OperationType {
74 Comment,
75 Declaration, // creg, qreg
76 Barrier,
78 Reset,
81 Uop,
82 CondUop,
83 };
84
87
88 std::string comment;
89
91
92 std::vector<int> qubits;
93 std::vector<int> cbits;
94
95 std::vector<double> parameters;
96
97 std::vector<std::string> paramsDecl;
98 std::vector<std::string> qubitsDecl;
99
100 int condValue = 0;
101 std::vector<UopType> declOps;
102};
103
105
107 boost::fusion::vector<std::vector<std::string>, double,
108 std::vector<std::string>, std::vector<StatementType>>;
109
111using MeasureType = boost::fusion::vector<ArgumentType, ArgumentType>;
113// using QopType = std::variant<UopType, ResetType, MeasureType, BarrierType>;
115using CondOpType = boost::fusion::vector<std::string, int, QopType>;
116
118 boost::fusion::vector<std::string, std::vector<std::string>,
119 std::vector<std::string>>;
120using SimpleBarrierType = std::vector<std::string>;
121using GateDeclOpType = std::variant<UopType, SimpleBarrierType>;
123 boost::fusion::vector<std::string, std::vector<std::string>,
124 std::vector<std::string>>;
125
127 struct result {
129 };
130
131 IndexedId operator()(int &counter,
132 std::unordered_map<std::string, IndexedId> &creg_map,
133 const IndexedId &id) const {
134 IndexedId id_copy = id;
135 id_copy.base = counter;
136
137 counter += static_cast<int>(std::round(id_copy.Eval()));
138
139 creg_map[id_copy.id] = id_copy;
140
141 id_copy.declType = "creg";
142
143 return id_copy;
144 }
145};
146
147phx::function<AddCregExpr> AddCreg;
148
150 struct result {
152 };
153
154 IndexedId operator()(int &counter,
155 std::unordered_map<std::string, IndexedId> &qreg_map,
156 const IndexedId &id) const {
157 IndexedId id_copy = id;
158 id_copy.base = counter;
159
160 counter += static_cast<int>(std::round(id_copy.Eval()));
161 qreg_map[id_copy.id] = id_copy;
162
163 id_copy.declType = "qreg";
164
165 return id_copy;
166 }
167};
168
169phx::function<AddQregExpr> AddQreg;
170
172 struct result {
174 };
175
176 QoperationStatement operator()(const std::string &comment) const {
178
180 stmt.comment = comment;
181
182 return stmt;
183 }
184};
185
186phx::function<AddCommentExpr> AddComment;
187
189 struct result {
191 };
192
196 stmt.declaration = id;
197
198 return stmt;
199 }
200};
201
202phx::function<AddDeclarationExpr> AddDeclaration;
203
205 struct result {
207 };
208
210 const MeasureType &measure,
211 const std::unordered_map<std::string, IndexedId> &creg_map,
212 const std::unordered_map<std::string, IndexedId> &qreg_map) const {
215
216 ArgumentType arg1 = boost::fusion::at_c<0>(measure); // qubits info
217
218 // there are two possibilities here, either it's an indexed id or a simple
219 // id
220 if (std::holds_alternative<IndexedId>(arg1)) {
221 IndexedId indexedId = std::get<IndexedId>(arg1);
222 auto it = qreg_map.find(indexedId.id);
223 if (it != qreg_map.end()) {
224 int base = it->second.base;
225 stmt.qubits.push_back(base + indexedId.index);
226 }
227 } else if (std::holds_alternative<std::string>(arg1)) {
228 std::string id = std::get<std::string>(arg1);
229 auto it = qreg_map.find(id);
230 if (it != qreg_map.end()) {
231 int base = it->second.base;
232 int size = static_cast<int>(std::round(it->second.Eval()));
233 for (int i = 0; i < size; ++i) stmt.qubits.push_back(base + i);
234 }
235 }
236
237 ArgumentType arg2 = boost::fusion::at_c<1>(measure); // cbits info
238 // there are two possibilities here, either it's an indexed id or a simple
239 // id
240
241 if (std::holds_alternative<IndexedId>(arg2)) {
242 IndexedId indexedId = std::get<IndexedId>(arg2);
243 auto it = creg_map.find(indexedId.id);
244 if (it != creg_map.end()) {
245 int base = it->second.base;
246 stmt.cbits.push_back(base + indexedId.index);
247 }
248 } else if (std::holds_alternative<std::string>(arg2)) {
249 std::string id = std::get<std::string>(arg2);
250 auto it = creg_map.find(id);
251 if (it != creg_map.end()) {
252 int base = it->second.base;
253 int size = static_cast<int>(std::round(it->second.Eval()));
254 for (int i = 0; i < size; ++i) stmt.cbits.push_back(base + i);
255 }
256 }
257
258 return stmt;
259 }
260};
261
262phx::function<AddMeasureExpr> AddMeasure;
263
265 struct result {
267 };
268
270 const ResetType &reset,
271 const std::unordered_map<std::string, IndexedId> &qreg_map) const {
274
275 // there are two possibilities here, either it's an indexed id or a simple
276 // id
277 if (std::holds_alternative<IndexedId>(reset)) {
278 IndexedId indexedId = std::get<IndexedId>(reset);
279 auto it = qreg_map.find(indexedId.id);
280 if (it != qreg_map.end()) {
281 int base = it->second.base;
282 stmt.qubits.push_back(base + indexedId.index);
283 }
284 } else if (std::holds_alternative<std::string>(reset)) {
285 std::string id = std::get<std::string>(reset);
286 auto it = qreg_map.find(id);
287 if (it != qreg_map.end()) {
288 int base = it->second.base;
289 int size = static_cast<int>(std::round(it->second.Eval()));
290 for (int i = 0; i < size; ++i) stmt.qubits.push_back(base + i);
291 }
292 }
293
294 return stmt;
295 }
296};
297
298phx::function<AddResetExpr> AddReset;
299
301 struct result {
303 };
304
306 const BarrierType &barrier,
307 const std::unordered_map<std::string, IndexedId> &qreg_map) const {
308 StatementType stmt;
310 std::set<int> qubit_set;
311
312 for (const auto &b : barrier) {
313 // there are two possibilities here, either it's an indexed id or a simple
314 // id
315 if (std::holds_alternative<IndexedId>(b)) {
316 IndexedId indexedId = std::get<IndexedId>(b);
317 auto it = qreg_map.find(indexedId.id);
318 if (it != qreg_map.end()) {
319 int base = it->second.base;
320 qubit_set.insert(base + indexedId.index);
321 }
322 } else if (std::holds_alternative<std::string>(b)) {
323 std::string id = std::get<std::string>(b);
324 auto it = qreg_map.find(id);
325 if (it != qreg_map.end()) {
326 int base = it->second.base;
327 int size = static_cast<int>(std::round(it->second.Eval()));
328 for (int i = 0; i < size; ++i) qubit_set.insert(base + i);
329 }
330 }
331 }
332
333 stmt.qubits.assign(qubit_set.begin(), qubit_set.end());
334
335 return stmt;
336 }
337};
338
339phx::function<AddBarrierExpr> AddBarrier;
340
342 struct result {
344 };
345
347 const OpaqueDeclType &opaqueDecl,
348 std::unordered_map<std::string, StatementType> &opaqueGates,
349 const std::unordered_map<std::string, IndexedId> &qreg_map) const {
350 StatementType stmt;
352
353 std::string gateName = boost::fusion::at_c<0>(opaqueDecl);
354
355 stmt.comment = gateName;
356
357 // maybe take some other infor from opaqueDecl if needed
358 const std::vector<std::string> &params = boost::fusion::at_c<1>(opaqueDecl);
359 const std::vector<std::string> &args = boost::fusion::at_c<2>(opaqueDecl);
360
361 stmt.paramsDecl = params;
362 stmt.qubitsDecl = args;
363
364 // save into the map as well
365 opaqueGates[gateName] = stmt;
366
367 return stmt;
368 }
369};
370
371phx::function<AddOpaqueDeclExpr> AddOpaqueDecl;
372
374 struct result {
376 };
377
379 const boost::fusion::vector<GateDeclType, std::vector<GateDeclOpType>>
380 &gateDecl,
381 std::unordered_map<std::string, StatementType> &definedGates) const {
382 StatementType stmt;
384
385 const GateDeclType &declInfo = boost::fusion::at_c<0>(gateDecl);
386
387 const std::string &gateName = boost::fusion::at_c<0>(declInfo);
388 const std::vector<std::string> &params = boost::fusion::at_c<1>(declInfo);
389 const std::vector<std::string> &args = boost::fusion::at_c<2>(declInfo);
390
391 if (args.empty())
392 throw std::invalid_argument(
393 "Gate declaration must have at least one qubit argument: " +
394 gateName);
395 else if (definedGates.find(gateName) !=
396 definedGates
397 .end()) // for now do not allow redefinition, the
398 // biggest problem is that defined gates can be
399 // used inside other defined gates, otherwise
400 // redefinition would be simple to handle
401 throw std::invalid_argument("Gate already defined: " + gateName);
402
403 stmt.comment = gateName;
404 stmt.paramsDecl = params;
405 stmt.qubitsDecl = args;
406
407 const std::vector<GateDeclOpType> &declOps =
408 boost::fusion::at_c<1>(gateDecl);
409
410 for (const auto &op : declOps) {
411 if (std::holds_alternative<UopType>(op)) {
412 const UopType &uop = std::get<UopType>(op);
413
414 stmt.declOps.push_back(uop);
415 }
416 // ignore barriers
417 // else if (std::holds_alternative<SimpleBarrierType>(op))
418 //{
419 //}
420 }
421
422 definedGates[gateName] = stmt;
423
424 return stmt;
425 }
426};
427
428phx::function<AddGateDeclExpr> AddGateDecl;
429} // namespace qasm
430
431#endif
double Eval() const
Definition SimpleOps.h:30
IndexedId(const std::string &id, int index)
Definition SimpleOps.h:26
std::string id
Definition SimpleOps.h:36
std::string declType
Definition SimpleOps.h:39
QuantumGateType
The type of quantum gates.
std::vector< std::string > SimpleBarrierType
Definition SimpleOps.h:120
std::variant< std::string, IndexedId > ArgumentType
Definition SimpleOps.h:58
boost::fusion::vector< std::string, MixedListType > SimpleGatecallType
Definition SimpleOps.h:61
ArgumentType ResetType
Definition SimpleOps.h:110
QoperationStatement StatementType
Definition SimpleOps.h:104
std::variant< double, int, std::string > SimpleExpType
Definition SimpleOps.h:56
MixedListType BarrierType
Definition SimpleOps.h:112
std::variant< UopType, SimpleBarrierType > GateDeclOpType
Definition SimpleOps.h:121
boost::fusion::vector< std::string, std::vector< std::string >, std::vector< std::string > > GateDeclType
Definition SimpleOps.h:119
phx::function< AddQregExpr > AddQreg
Definition SimpleOps.h:169
std::variant< SimpleGatecallType, ExpGatecallType > GatecallType
Definition SimpleOps.h:64
boost::fusion::vector< std::vector< Expression >, ArgumentType > UGateCallType
Definition SimpleOps.h:67
phx::function< MakeIndexedIdExpression > MakeIndexedId
Definition SimpleOps.h:54
std::variant< UGateCallType, CXGateCallType, GatecallType > UopType
Definition SimpleOps.h:70
phx::function< AddCommentExpr > AddComment
Definition SimpleOps.h:186
boost::fusion::vector< std::string, int, QopType > CondOpType
Definition SimpleOps.h:115
boost::fusion::vector< std::string, std::vector< std::string >, std::vector< std::string > > OpaqueDeclType
Definition SimpleOps.h:124
phx::function< AddDeclarationExpr > AddDeclaration
Definition SimpleOps.h:202
phx::function< AddBarrierExpr > AddBarrier
Definition SimpleOps.h:339
boost::fusion::vector< std::string, std::vector< Expression >, MixedListType > ExpGatecallType
Definition SimpleOps.h:63
phx::function< AddCregExpr > AddCreg
Definition SimpleOps.h:147
phx::function< AddOpaqueDeclExpr > AddOpaqueDecl
Definition SimpleOps.h:371
boost::fusion::vector< ArgumentType, ArgumentType > MeasureType
Definition SimpleOps.h:111
boost::fusion::vector< ArgumentType, ArgumentType > CXGateCallType
Definition SimpleOps.h:68
phx::function< AddMeasureExpr > AddMeasure
Definition SimpleOps.h:262
boost::fusion::vector< std::vector< std::string >, double, std::vector< std::string >, std::vector< StatementType > > ProgramType
Definition SimpleOps.h:108
phx::function< AddGateDeclExpr > AddGateDecl
Definition SimpleOps.h:428
std::vector< ArgumentType > MixedListType
Definition SimpleOps.h:59
phx::function< AddResetExpr > AddReset
Definition SimpleOps.h:298
QoperationStatement type
Definition SimpleOps.h:302
QoperationStatement operator()(const BarrierType &barrier, const std::unordered_map< std::string, IndexedId > &qreg_map) const
Definition SimpleOps.h:305
QoperationStatement operator()(const std::string &comment) const
Definition SimpleOps.h:176
QoperationStatement type
Definition SimpleOps.h:173
IndexedId operator()(int &counter, std::unordered_map< std::string, IndexedId > &creg_map, const IndexedId &id) const
Definition SimpleOps.h:131
QoperationStatement operator()(const IndexedId &id) const
Definition SimpleOps.h:193
QoperationStatement type
Definition SimpleOps.h:375
QoperationStatement operator()(const boost::fusion::vector< GateDeclType, std::vector< GateDeclOpType > > &gateDecl, std::unordered_map< std::string, StatementType > &definedGates) const
Definition SimpleOps.h:378
QoperationStatement operator()(const MeasureType &measure, const std::unordered_map< std::string, IndexedId > &creg_map, const std::unordered_map< std::string, IndexedId > &qreg_map) const
Definition SimpleOps.h:209
QoperationStatement type
Definition SimpleOps.h:206
QoperationStatement type
Definition SimpleOps.h:343
QoperationStatement operator()(const OpaqueDeclType &opaqueDecl, std::unordered_map< std::string, StatementType > &opaqueGates, const std::unordered_map< std::string, IndexedId > &qreg_map) const
Definition SimpleOps.h:346
IndexedId operator()(int &counter, std::unordered_map< std::string, IndexedId > &qreg_map, const IndexedId &id) const
Definition SimpleOps.h:154
QoperationStatement operator()(const ResetType &reset, const std::unordered_map< std::string, IndexedId > &qreg_map) const
Definition SimpleOps.h:269
QoperationStatement type
Definition SimpleOps.h:266
IndexedId operator()(const ID &id, IND index) const
Definition SimpleOps.h:49
std::vector< UopType > declOps
Definition SimpleOps.h:101
std::vector< std::string > qubitsDecl
Definition SimpleOps.h:98
std::vector< double > parameters
Definition SimpleOps.h:95
std::vector< int > cbits
Definition SimpleOps.h:93
std::vector< std::string > paramsDecl
Definition SimpleOps.h:97
std::vector< int > qubits
Definition SimpleOps.h:92
Circuits::QuantumGateType gateType
Definition SimpleOps.h:86