Maestro 0.1.0
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
CircQasm.h
Go to the documentation of this file.
1
11
12#pragma once
13
14#ifndef _CIRCQASM_H_
15#define _CIRCQASM_H_
16
17#include "Circuit/Circuit.h"
18
19namespace qasm {
20
21template <typename Time = Types::time_type> class CircToQasm {
22public:
23 enum class QasmGateType : size_t {
24 X, // XGate
25 Y, // YGate
26 Z, // ZGate
27 H, // HadamardGate
28 S, // SGate
29 SDG, // SdgGate
30 Sx, // SxGate
31 SxDG, // SxDagGate
32 K, // KGate
33 T, // TGate
34 TDG, // TdgGate
35 Rx, // RxGate
36 Ry, // RyGate
37 Rz, // RzGate
38 U, // UGate
39 CZ, // CZGate
40 CY, // CYGate
41 CH, // CHGate
42 CRZ, // CRzGate
43 CU1, // CPGate
44 CU3, // CUGate
45 CRX, // CRxGate
46 CRY, // CRyGate
49 CSX, // CSxGate
50 CSXDAG, // CSxDagGate
54 };
55
56 // still need to be defined additionally:
57
58 /*
59 kCUGateType
60 */
61
62 static std::string GenerateWithMapping(
63 const std::shared_ptr<Circuits::Circuit<Time>> &circuit,
64 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap) {
65 const auto mappedCircuit =
66 std::static_pointer_cast<Circuits::Circuit<Time>>(
67 circuit->Remap(bitsMap, bitsMap));
68
69 return GenerateFromCircuit(mappedCircuit, false);
70 }
71
72 // look over the circuit and convert it to qasm
73 // identify which gates are used, generate gate definitions only for those
74 // (that do not exist in the qasm standard) the standard ones are U3 and CX
75 // attention: the definitions depend on other ones, so the order is important,
76 // also some gates that are not used in the circuit still need to be defined
77 // if they are used in the definitions of the gates that are used
78
79 static std::string
80 Generate(const std::shared_ptr<Circuits::Circuit<Time>> &circuit) {
81 return GenerateFromCircuit(circuit, true);
82 }
83
84private:
85 static std::string
86 GenerateFromCircuit(const std::shared_ptr<Circuits::Circuit<Time>> &circuit,
87 bool clone) {
88 if (circuit->empty())
89 return "";
90
91 const auto circ =
92 (clone ? std::static_pointer_cast<Circuits::Circuit<Time>>(
93 circuit->Clone())
94 : circuit);
95
96 circ->ConvertForDistribution(); // get rid of swap and 3 qubit gates
97
98 std::string qasm = QasmHeader();
99
100 qasm += QasmGatesAndRegsDefinitions(circ);
101
102 // iterate over the circuit and generate the qasm
103 for (const auto &gate : circ->GetOperations())
104 qasm += OperationToQasm(gate);
105
106 return qasm;
107 }
108
109 static std::string OperationToQasm(
110 const std::shared_ptr<Circuits::IOperation<Time>> &operation) {
111 std::string qasm;
112
113 switch (operation->GetType()) {
115 qasm += GateToQasm(operation);
116 break;
118 auto qbits = operation->AffectedQubits();
119 auto bits = operation->AffectedBits();
120
121 assert(qbits.size() == bits.size());
122
123 for (size_t i = 0; i < qbits.size(); ++i)
124 qasm += "measure q[" + std::to_string(qbits[i]) + "]->c" +
125 std::to_string(bits[i]) + "[0];\n";
126 } break;
128 auto qbits = operation->AffectedQubits();
129 for (const auto &qbit : qbits)
130 qasm += "reset q[" + std::to_string(qbit) + "];\n";
131 } break;
133 [[fallthrough]];
135 // conditionals are similar, generate an if and then call again for the
136 // conditioned operations
137 {
138 auto condop =
139 std::static_pointer_cast<Circuits::IConditionalOperation<Time>>(
140 operation);
141 auto bits = condop->AffectedBits();
142 auto vals = std::static_pointer_cast<Circuits::EqualCondition>(
143 condop->GetCondition())
144 ->GetAllBits();
145 assert(bits.size() == vals.size());
146
147 for (size_t i = 0; i < bits.size(); ++i)
148 qasm += "if(c" + std::to_string(bits[i]) +
149 "==" + std::to_string(vals[i] ? 1 : 0) + ") ";
150
151 const auto theop = condop->GetOperation();
152 qasm += OperationToQasm(theop);
153 }
154 break;
156 qasm += "barrier q;\n";
157 break;
159 [[fallthrough]];
161 [[fallthrough]];
163 throw std::runtime_error("Not supported!");
164 break;
165 }
166
167 return qasm;
168 }
169
170 static std::string
171 GateToQasm(const std::shared_ptr<Circuits::IOperation<Time>> &operation) {
172 if (!operation || operation->GetType() != Circuits::OperationType::kGate)
173 return "";
174
175 const auto gate =
176 std::static_pointer_cast<Circuits::IQuantumGate<Time>>(operation);
177
178 std::string qasm;
179
180 switch (gate->GetGateType()) {
182 qasm += "U(0,0," + std::to_string(gate->GetParams()[0]) + ") q[" +
183 std::to_string(gate->GetQubit(0)) + "];\n";
184 break;
186 qasm += "x q[" + std::to_string(gate->GetQubit(0)) + "];\n";
187 break;
189 qasm += "y q[" + std::to_string(gate->GetQubit(0)) + "];\n";
190 break;
192 qasm += "z q[" + std::to_string(gate->GetQubit(0)) + "];\n";
193 break;
195 qasm += "h q[" + std::to_string(gate->GetQubit(0)) + "];\n";
196 break;
198 qasm += "s q[" + std::to_string(gate->GetQubit(0)) + "];\n";
199 break;
201 qasm += "sdg q[" + std::to_string(gate->GetQubit(0)) + "];\n";
202 break;
204 qasm += "t q[" + std::to_string(gate->GetQubit(0)) + "];\n";
205 break;
207 qasm += "tdg q[" + std::to_string(gate->GetQubit(0)) + "];\n";
208 break;
209
210 //*************************************************************************************************
211 // defined here, not in the 'standard' header
213 qasm += "sx q[" + std::to_string(gate->GetQubit(0)) + "];\n";
214 break;
216 qasm += "sxdg q[" + std::to_string(gate->GetQubit(0)) + "];\n";
217 break;
219 qasm += "k q[" + std::to_string(gate->GetQubit(0)) + "];\n";
220 break;
221 //*************************************************************************************************
222
224 qasm += "rx(" + std::to_string(gate->GetParams()[0]) + ") q[" +
225 std::to_string(gate->GetQubit(0)) + "];\n";
226 break;
228 qasm += "ry(" + std::to_string(gate->GetParams()[0]) + ") q[" +
229 std::to_string(gate->GetQubit(0)) + "];\n";
230 break;
232 qasm += "rz(" + std::to_string(gate->GetParams()[0]) + ") q[" +
233 std::to_string(gate->GetQubit(0)) + "];\n";
234 break;
236 if (gate->GetParams()[3] == 0)
237 qasm += "U(" + std::to_string(gate->GetParams()[0]) + "," +
238 std::to_string(gate->GetParams()[1]) + "," +
239 std::to_string(gate->GetParams()[2]) + ") q[" +
240 std::to_string(gate->GetQubit(0)) + "];\n";
241 else
242 throw std::runtime_error("U with gamma non zero not supported yet!");
243 break;
244
246 // first is the control qubit!
247 qasm += "CX q[" + std::to_string(gate->GetQubit(0)) + "],q[" +
248 std::to_string(gate->GetQubit(1)) + "];\n";
249 break;
251 qasm += "cy q[" + std::to_string(gate->GetQubit(0)) + "],q[" +
252 std::to_string(gate->GetQubit(1)) + "];\n";
253 break;
255 qasm += "cz q[" + std::to_string(gate->GetQubit(0)) + "],q[" +
256 std::to_string(gate->GetQubit(1)) + "];\n";
257 break;
259 qasm += "cu1(" + std::to_string(gate->GetParams()[0]) + ") q[" +
260 std::to_string(gate->GetQubit(0)) + "],q[" +
261 std::to_string(gate->GetQubit(1)) + "];\n";
262 break;
263
264 //*************************************************************************************************
265 // defined here, not in the 'standard' header
267 qasm += "crx(" + std::to_string(gate->GetParams()[0]) + ") q[" +
268 std::to_string(gate->GetQubit(0)) + "],q[" +
269 std::to_string(gate->GetQubit(1)) + "];\n";
270 break;
272 qasm += "cry(" + std::to_string(gate->GetParams()[0]) + ") q[" +
273 std::to_string(gate->GetQubit(0)) + "],q[" +
274 std::to_string(gate->GetQubit(1)) + "];\n";
275 break;
276 //*************************************************************************************************
277
279 qasm += "crz(" + std::to_string(gate->GetParams()[0]) + ") q[" +
280 std::to_string(gate->GetQubit(0)) + "],q[" +
281 std::to_string(gate->GetQubit(1)) + "];\n";
282 break;
284 qasm += "ch q[" + std::to_string(gate->GetQubit(0)) + "],q[" +
285 std::to_string(gate->GetQubit(1)) + "];\n";
286 break;
287
288 //*************************************************************************************************
289 // defined here, not in the 'standard' header
291 qasm += "csx q[" + std::to_string(gate->GetQubit(0)) + "],q[" +
292 std::to_string(gate->GetQubit(1)) + "];\n";
293 break;
295 qasm += "csxdag q[" + std::to_string(gate->GetQubit(0)) + "],q[" +
296 std::to_string(gate->GetQubit(1)) + "];\n";
297 break;
298
299 // we have a problem with this, our CU is with 4 parameters, so not fully
300 // converted if the 4th parameter is not zero!
302 if (gate->GetParams()[3] == 0)
303 qasm += "cu3(" + std::to_string(gate->GetParams()[0]) + "," +
304 std::to_string(gate->GetParams()[1]) + "," +
305 std::to_string(gate->GetParams()[2]) + ") q[" +
306 std::to_string(gate->GetQubit(0)) + "], q[" +
307 std::to_string(gate->GetQubit(1)) + "];\n";
308 else
309 throw std::runtime_error("CU with gamma non zero not supported yet!");
310 break;
311 //*************************************************************************************************
312
313 // swap is converted to three CX gates
315 qasm += "swap q[" + std::to_string(gate->GetQubit(0)) + "],q[" +
316 std::to_string(gate->GetQubit(1)) + "];\n";
317 break;
318 // three qubit gates, do not need to be converted as they are converted to
319 // two qubit gates already
321 [[fallthrough]];
323 throw std::runtime_error("Not supported!");
324 break;
325 }
326
327 return qasm;
328 }
329
330 static std::string QasmHeader() {
331 std::string qasm = "OPENQASM 2.0;\n";
332
333 return qasm;
334 }
335
336 // assume qubits and cbits starting from 0, map the circuit to that if not
337 // already like that
338 static std::string
339 QasmRegisters(const std::shared_ptr<Circuits::Circuit<Time>> &circuit) {
340 const auto nrq = circuit->GetMaxQubitIndex() + 1;
341
342 const std::string nrq_str = std::to_string(nrq);
343
344 std::string qasm = "qreg q[" + nrq_str + "];\n";
345
346 std::set<size_t> measQubits;
347
348 for (const auto &op : *circuit) {
349 const auto bits = op->AffectedBits();
350
351 for (auto bit : bits)
352 measQubits.insert(bit);
353 }
354
355 int creg_count = 0;
356 for (auto bit : measQubits) {
357 // this completion is needed to have a proper total cregister definition
358 // we need this to be able to address the bits properly, otherwise
359 // conversion circuit -> qasm -> circuit would not work properly
360 if (creg_count < static_cast<int>(bit))
361 qasm += "creg c" + std::to_string(creg_count) + "[" +
362 std::to_string(bit - creg_count) + "];\n";
363
364 qasm += "creg c" + std::to_string(bit) + "[1];\n";
365 creg_count = bit + 1;
366 }
367
368 return qasm;
369 }
370
371 static std::string QasmGatesAndRegsDefinitions(
372 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) {
373 std::vector<bool> neededGates(static_cast<size_t>(QasmGateType::NoGate),
374 false);
375
376 // #define DONT_USE_HEADER_DEFINITIONS 1
377
378 for (const auto &op : circuit->GetOperations()) {
379 const auto opType = op->GetType();
380 if (opType == Circuits::OperationType::kGate ||
382 const auto &gate =
383 std::static_pointer_cast<Circuits::IQuantumGate<Time>>(
385 ? std::static_pointer_cast<
386 Circuits::IConditionalOperation<Time>>(op)
387 ->GetOperation()
388 : op);
389
390 switch (gate->GetGateType()) {
392#ifdef DONT_USE_HEADER_DEFINITIONS
393 neededGates[static_cast<size_t>(QasmGateType::U)] = true;
394#else
395 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
396#endif
397 break;
399#ifdef DONT_USE_HEADER_DEFINITIONS
400 neededGates[static_cast<size_t>(QasmGateType::X)] = true;
401#else
402 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
403#endif
404 break;
406#ifdef DONT_USE_HEADER_DEFINITIONS
407 neededGates[static_cast<size_t>(QasmGateType::Y)] = true;
408#else
409 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
410#endif
411 break;
413#ifdef DONT_USE_HEADER_DEFINITIONS
414 neededGates[static_cast<size_t>(QasmGateType::Z)] = true;
415#else
416 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
417#endif
418 break;
420#ifdef DONT_USE_HEADER_DEFINITIONS
421 neededGates[static_cast<size_t>(QasmGateType::H)] = true;
422#else
423 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
424#endif
425 break;
427#ifdef DONT_USE_HEADER_DEFINITIONS
428 neededGates[static_cast<size_t>(QasmGateType::S)] = true;
429#else
430 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
431#endif
432 break;
434#ifdef DONT_USE_HEADER_DEFINITIONS
435 neededGates[static_cast<size_t>(QasmGateType::SDG)] = true;
436#else
437 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
438#endif
439 break;
441#ifdef DONT_USE_HEADER_DEFINITIONS
442 neededGates[static_cast<size_t>(QasmGateType::T)] = true;
443#else
444 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
445#endif
446 break;
448#ifdef DONT_USE_HEADER_DEFINITIONS
449 neededGates[static_cast<size_t>(QasmGateType::TDG)] = true;
450#else
451 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
452#endif
453 break;
454
455 //*************************************************************************************************
456 // defined here, not in the 'standard' header
458 neededGates[static_cast<size_t>(QasmGateType::Sx)] = true;
459#ifndef DONT_USE_HEADER_DEFINITIONS
460 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
461#endif
462 break;
464 neededGates[static_cast<size_t>(QasmGateType::SxDG)] = true;
465#ifndef DONT_USE_HEADER_DEFINITIONS
466 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
467#endif
468 break;
470 neededGates[static_cast<size_t>(QasmGateType::K)] = true;
471#ifndef DONT_USE_HEADER_DEFINITIONS
472 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
473#endif
474 break;
475 //*************************************************************************************************
476
478#ifdef DONT_USE_HEADER_DEFINITIONS
479 neededGates[static_cast<size_t>(QasmGateType::Rx)] = true;
480#else
481 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
482#endif
483 break;
485#ifdef DONT_USE_HEADER_DEFINITIONS
486 neededGates[static_cast<size_t>(QasmGateType::Ry)] = true;
487#else
488 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
489#endif
490 break;
492#ifdef DONT_USE_HEADER_DEFINITIONS
493 neededGates[static_cast<size_t>(QasmGateType::Rz)] = true;
494#else
495 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
496#endif
497 break;
498
500#ifdef DONT_USE_HEADER_DEFINITIONS
501 neededGates[static_cast<size_t>(QasmGateType::U)] = true;
502#else
503 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
504#endif
505 break;
506
508 // standard gate
509#ifndef DONT_USE_HEADER_DEFINITIONS
510 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
511#endif
512 break;
514#ifdef DONT_USE_HEADER_DEFINITIONS
515 neededGates[static_cast<size_t>(QasmGateType::CY)] = true;
516 neededGates[static_cast<size_t>(QasmGateType::SDG)] = true;
517 neededGates[static_cast<size_t>(QasmGateType::S)] = true;
518#else
519 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
520#endif
521 break;
523#ifdef DONT_USE_HEADER_DEFINITIONS
524 neededGates[static_cast<size_t>(QasmGateType::CZ)] = true;
525 neededGates[static_cast<size_t>(QasmGateType::H)] = true;
526#else
527 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
528#endif
529 break;
531#ifdef DONT_USE_HEADER_DEFINITIONS
532 neededGates[static_cast<size_t>(QasmGateType::CU1)] = true;
533#else
534 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
535#endif
536 break;
537
538 //*************************************************************************************************
539 // defined here, not in the 'standard' header
541 neededGates[static_cast<size_t>(QasmGateType::CRX)] = true;
542#ifdef DONT_USE_HEADER_DEFINITIONS
543 neededGates[static_cast<size_t>(QasmGateType::CU3)] = true;
544#else
545 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
546#endif
547 break;
549 neededGates[static_cast<size_t>(QasmGateType::CRY)] = true;
550#ifdef DONT_USE_HEADER_DEFINITIONS
551 neededGates[static_cast<size_t>(QasmGateType::CU3)] = true;
552#else
553 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
554#endif
555 break;
556 //*************************************************************************************************
557
559#ifdef DONT_USE_HEADER_DEFINITIONS
560 neededGates[static_cast<size_t>(QasmGateType::CRZ)] = true;
561#else
562 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
563#endif
564 break;
566#ifdef DONT_USE_HEADER_DEFINITIONS
567 neededGates[static_cast<size_t>(QasmGateType::CH)] = true;
568 neededGates[static_cast<size_t>(QasmGateType::H)] = true;
569 neededGates[static_cast<size_t>(QasmGateType::SDG)] = true;
570 neededGates[static_cast<size_t>(QasmGateType::T)] = true;
571 neededGates[static_cast<size_t>(QasmGateType::S)] = true;
572 neededGates[static_cast<size_t>(QasmGateType::X)] = true;
573#else
574 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
575#endif
576 break;
577
578 //*************************************************************************************************
579 // defined here, not in the 'standard' header
581 neededGates[static_cast<size_t>(QasmGateType::CSX)] = true;
582 neededGates[static_cast<size_t>(QasmGateType::CS)] = true;
583 break;
585 neededGates[static_cast<size_t>(QasmGateType::CSXDAG)] = true;
586 neededGates[static_cast<size_t>(QasmGateType::CSDAG)] = true;
587 break;
588
589 // we have a problem with this, our CU is with 4 parameters, so not
590 // fully converted if the 4th parameter is not zero!
592 if (gate->GetParams()[3] == 0) {
593#ifdef DONT_USE_HEADER_DEFINITIONS
594 neededGates[static_cast<size_t>(QasmGateType::CU3)] = true;
595#else
596 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
597#endif
598 } else
599 throw std::runtime_error(
600 "CU with gamma non zero not supported yet!");
601 break;
602 //*************************************************************************************************
603
604 // swap is converted to three CX gates
606 neededGates[static_cast<size_t>(QasmGateType::SWAP)] = true;
607 break;
608 // three qubit gates, do not need to be converted as they are
609 // converted to two qubit gates already
611 [[fallthrough]];
613 throw std::runtime_error("Not supported!");
614 break;
615 }
616 }
617 }
618
619 std::string qasm;
620
621 if (neededGates[static_cast<size_t>(QasmGateType::IncludedGate)])
622 qasm += "include \"qelib1.inc\";\n";
623
624 qasm += QasmRegisters(circuit);
625
626 // WARNING: order matters, so be sure you won't define gates based on gates
627 // that are defined later here
628
629 if (neededGates[static_cast<size_t>(QasmGateType::X)])
630 qasm += XGateDefinition();
631 if (neededGates[static_cast<size_t>(QasmGateType::Y)])
632 qasm += YGateDefinition();
633 if (neededGates[static_cast<size_t>(QasmGateType::Z)])
634 qasm += ZGateDefinition();
635 if (neededGates[static_cast<size_t>(QasmGateType::H)])
636 qasm += HGateDefinition();
637 if (neededGates[static_cast<size_t>(QasmGateType::S)])
638 qasm += SGateDefinition();
639 if (neededGates[static_cast<size_t>(QasmGateType::SDG)])
640 qasm += SDGGateDefinition();
641
642 if (neededGates[static_cast<size_t>(QasmGateType::Sx)])
643 qasm += SxGateDefinition();
644 if (neededGates[static_cast<size_t>(QasmGateType::SxDG)])
645 qasm += SxDGGateDefinition();
646
647 if (neededGates[static_cast<size_t>(QasmGateType::K)])
648 qasm += KGateDefinition();
649
650 if (neededGates[static_cast<size_t>(QasmGateType::T)])
651 qasm += TGateDefinition();
652 if (neededGates[static_cast<size_t>(QasmGateType::TDG)])
653 qasm += TDGGateDefinition();
654
655 if (neededGates[static_cast<size_t>(QasmGateType::Rx)])
656 qasm += RxGateDefinition();
657 if (neededGates[static_cast<size_t>(QasmGateType::Ry)])
658 qasm += RyGateDefinition();
659 if (neededGates[static_cast<size_t>(QasmGateType::Rz)])
660 qasm += RzGateDefinition();
661
662 if (neededGates[static_cast<size_t>(QasmGateType::CZ)])
663 qasm += CZGateDefinition();
664 if (neededGates[static_cast<size_t>(QasmGateType::CY)])
665 qasm += CYGateDefinition();
666 if (neededGates[static_cast<size_t>(QasmGateType::CH)])
667 qasm += CHGateDefinition();
668 // qasm += CCXGateDefinition();
669
670 if (neededGates[static_cast<size_t>(QasmGateType::CRZ)])
671 qasm += CRZGateDefinition();
672 if (neededGates[static_cast<size_t>(QasmGateType::CU1)])
673 qasm += CU1GateDefinition();
674 if (neededGates[static_cast<size_t>(QasmGateType::CU3)])
675 qasm += CU3GateDefinition();
676 if (neededGates[static_cast<size_t>(QasmGateType::CRX)])
677 qasm += CRXGateDefinition();
678 if (neededGates[static_cast<size_t>(QasmGateType::CRY)])
679 qasm += CRYGateDefinition();
680 if (neededGates[static_cast<size_t>(QasmGateType::SWAP)])
681 qasm += SwapGateDefinition();
682
683 if (neededGates[static_cast<size_t>(QasmGateType::CS)])
684 qasm += CSGateDefinition();
685 if (neededGates[static_cast<size_t>(QasmGateType::CSDAG)])
686 qasm += CSDAGGateDefinition();
687
688 if (neededGates[static_cast<size_t>(QasmGateType::CSX)])
689 qasm += CSXGateDefinition();
690 if (neededGates[static_cast<size_t>(QasmGateType::CSXDAG)])
691 qasm += CSXDAGGateDefinition();
692
693 return qasm;
694 }
695
696 // gates definitions
697 static std::string U3GateDefinition() {
698 return "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }\n";
699 }
700
701 static std::string U2GateDefinition() {
702 return "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }\n";
703 }
704
705 static std::string U1GateDefinition() {
706 return "gate u1(lambda) q { U(0,0,lambda) q; }\n";
707 }
708
709 static std::string XGateDefinition() {
710 return "gate x a { U(pi,0,pi) a; }\n";
711 }
712
713 static std::string YGateDefinition() {
714 return "gate y a { U(pi,pi/2,pi/2) a; }\n";
715 }
716
717 static std::string ZGateDefinition() { return "gate z a { U(0,0,pi) a; }\n"; }
718
719 static std::string HGateDefinition() {
720 return "gate h a { U(pi/2,0,pi) a; }\n";
721 }
722
723 static std::string SGateDefinition() {
724 return "gate s a { U(0,0,pi/2) a; }\n";
725 }
726
727 static std::string SDGGateDefinition() {
728 return "gate sdg a { U(0,0,-pi/2) a; }\n";
729 }
730
731 // the following two introduce a global phase compared with the operators for
732 // sx and sxdg, but that should be ok
733 static std::string SxGateDefinition() {
734 return "gate sx a { U(pi/2,-pi/2,pi/2) a; }\n"; // this is a rotation,
735 // equivalent up to a global
736 // phase
737 }
738
739 static std::string SxDGGateDefinition() {
740 return "gate sxdg a { U(-pi/2,-pi/2,pi/2) a; }\n";
741 }
742
743 static std::string KGateDefinition() {
744 return "gate k a { U(pi/2,pi/2,pi/2) a; }\n";
745 }
746
747 static std::string TGateDefinition() {
748 return "gate t a { U(0,0,pi/4) a; }\n";
749 }
750
751 static std::string TDGGateDefinition() {
752 return "gate tdg a { U(0,0,-pi/4) a; }\n";
753 }
754
755 static std::string RxGateDefinition() {
756 return "gate rx(theta) a { U(theta,-pi/2,pi/2) a; }\n";
757 }
758
759 static std::string RyGateDefinition() {
760 return "gate ry(theta) a { U(theta,0,0) a; }\n";
761 }
762
763 static std::string RzGateDefinition() {
764 return "gate rz(phi) a { U(0,0,phi) a; }\n";
765 }
766
767 static std::string SwapGateDefinition() {
768 return "gate swap a,b { CX a,b; CX b,a; CX a,b; }\n";
769 }
770
771 // with hadamard it's going to the x basis... then after cx, back to the z
772 // basis, applying hadamard again
773 static std::string CZGateDefinition() {
774 return "gate cz a,b { h b; CX a,b; h b; }\n";
775 }
776
777 static std::string CYGateDefinition() {
778 return "gate cy a,b { sdg b; CX a,b; s b; }\n";
779 }
780
781 static std::string CHGateDefinition() {
782 return "gate ch a,b { h b; sdg b; CX a,b; h b; t b; CX a,b; t b; h b; s b; "
783 "x b; s a; }\n";
784 }
785
786 static std::string CCXGateDefinition() {
787 return "gate ccx a,b,c\
788 {\
789 h c;\
790 cx b, c; tdg c;\
791 cx a, c; t c;\
792 cx b, c; tdg c;\
793 cx a, c; t b; t c; h c;\
794 cx a, b; t a; tdg b;\
795 cx a, b;\
796 }\n";
797 }
798
799 static std::string CU1GateDefinition() {
800 return "gate cu1(lambda) a,b { U(0,0,lambda/2) a; CX a,b; U(0,0,-lambda/2) "
801 "b; CX a,b; U(0,0,lambda/2) b; }\n";
802 }
803
804 static std::string CU3GateDefinition() {
805 return "gate cu3(theta,phi,lambda) c,t { U(0,0,(lambda+phi)/2) c; "
806 "U(0,0,(lambda-phi)/2) t; CX c,t; U(-theta/2,0,-(phi+lambda)/2) t; "
807 "CX c,t; U(theta/2,phi,0) t; }\n";
808 }
809
810 //*************************************************************************************************
811 // defined here, not in the 'standard' header
812
813 static std::string CRXGateDefinition() {
814 return "gate crx(theta) a,b { cu3(theta,-pi/2,pi/2) a,b; }\n";
815 }
816
817 static std::string CRYGateDefinition() {
818 return "gate cry(theta) a,b { cu3(theta,0,0) a,b; }\n";
819 }
820
821 static std::string CRZGateDefinition() {
822 return "gate crz(lambda) a,b { U(0,0,lambda/2) b; CX a,b; U(0,0,-lambda/2) "
823 "b; CX a,b; }\n";
824 }
825
826 static std::string CSGateDefinition() {
827 return "gate cs c,t { U(0,0,pi/4) c; U(0,0,pi/4) t; CX c,t; U(0,0,-pi/4) "
828 "t; CX c,t; }\n";
829 }
830
831 static std::string CSDAGGateDefinition() {
832 return "gate csdag c,t { CX c,t; U(0,0,pi/4) t; CX c,t; U(0,0,-pi/4) c; "
833 "U(0,0,-pi/4) t; }\n";
834 }
835
836 static std::string CSXGateDefinition() {
837 return "gate csx c,t { U(pi/2,0,pi) t; cs c,t; U(pi/2,0,pi) t; }\n";
838 }
839
840 static std::string CSXDAGGateDefinition() {
841 return "gate csxdag c,t { U(pi/2,0,pi) t; csdag c,t; U(pi/2,0,pi) t; }\n";
842 }
843};
844
845} // namespace qasm
846
847#endif
Circuit class for holding the sequence of operations.
Definition Circuit.h:45
The operation interface.
Definition Operations.h:361
static std::string Generate(const std::shared_ptr< Circuits::Circuit< Time > > &circuit)
Definition CircQasm.h:80
static std::string GenerateWithMapping(const std::shared_ptr< Circuits::Circuit< Time > > &circuit, const std::unordered_map< Types::qubit_t, Types::qubit_t > &bitsMap)
Definition CircQasm.h:62
@ kConditionalGate
conditional gate, similar with gate, but conditioned on something from 'OperationState'
Definition Operations.h:30
@ kNoOp
no operation, just a placeholder, could be used to erase some operation from a circuit
Definition Operations.h:41
@ kComposite
a composite operation, contains other operations - should not be used in the beginning,...
Definition Operations.h:43
@ kRandomGen
random classical bit generator, result in 'OperationState'
Definition Operations.h:29
@ kConditionalRandomGen
conditional random generator, similar with random gen, but conditioned on something from 'OperationSt...
Definition Operations.h:35
@ kConditionalMeasurement
conditional measurement, similar with measurement, but conditioned on something from 'OperationState'
Definition Operations.h:32
@ kMeasurement
measurement, result in 'OperationState'
Definition Operations.h:28
@ kGate
the usual quantum gate, result stays in simulator's state
Definition Operations.h:27
@ kReset
reset, no result in 'state', just apply measurement, then apply not on all qubits that were measured ...
Definition Operations.h:38