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