Maestro 0.2.5
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
CircQasm.h
Go to the documentation of this file.
1
13#pragma once
14
15#ifndef _CIRCQASM_H_
16#define _CIRCQASM_H_
17
18#include "../Circuit/Circuit.h"
19
20namespace qasm {
21
22template <typename Time = Types::time_type>
24 public:
25 enum class QasmGateType : size_t {
26 X, // XGate
27 Y, // YGate
28 Z, // ZGate
29 H, // HadamardGate
30 S, // SGate
31 SDG, // SdgGate
32 Sx, // SxGate
33 SxDG, // SxDagGate
34 K, // KGate
35 T, // TGate
36 TDG, // TdgGate
37 Rx, // RxGate
38 Ry, // RyGate
39 Rz, // RzGate
40 U, // UGate
41 CZ, // CZGate
42 CY, // CYGate
43 CH, // CHGate
44 CRZ, // CRzGate
45 CU1, // CPGate
46 CU3, // CUGate
47 CRX, // CRxGate
48 CRY, // CRyGate
49 CS,
50 CSDAG,
51 CSX, // CSxGate
52 CSXDAG, // CSxDagGate
53 SWAP,
55 NoGate
56 };
57
58 // still need to be defined additionally:
59
60 /*
61 kCUGateType
62 */
63
64 static std::string GenerateWithMapping(
65 const std::shared_ptr<Circuits::Circuit<Time>> &circuit,
66 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap) {
67 const auto mappedCircuit =
68 std::static_pointer_cast<Circuits::Circuit<Time>>(
69 circuit->Remap(bitsMap, bitsMap));
70
71 return GenerateFromCircuit(mappedCircuit, false);
72 }
73
74 // look over the circuit and convert it to qasm
75 // identify which gates are used, generate gate definitions only for those
76 // (that do not exist in the qasm standard) the standard ones are U3 and CX
77 // attention: the definitions depend on other ones, so the order is important,
78 // also some gates that are not used in the circuit still need to be defined
79 // if they are used in the definitions of the gates that are used
80
81 static std::string Generate(
82 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) {
83 return GenerateFromCircuit(circuit, true);
84 }
85
86 private:
87 static std::string GenerateFromCircuit(
88 const std::shared_ptr<Circuits::Circuit<Time>> &circuit, bool clone) {
89 if (circuit->empty()) 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 GateToQasm(
171 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;
326 break;
327 }
328
329 return qasm;
330 }
331
332 static std::string QasmHeader() {
333 std::string qasm = "OPENQASM 2.0;\n";
334
335 return qasm;
336 }
337
338 // assume qubits and cbits starting from 0, map the circuit to that if not
339 // already like that
340 static std::string QasmRegisters(
341 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) {
342 const auto nrq = circuit->GetMaxQubitIndex() + 1;
343
344 const std::string nrq_str = std::to_string(nrq);
345
346 std::string qasm = "qreg q[" + nrq_str + "];\n";
347
348 std::set<size_t> measQubits;
349
350 for (const auto &op : *circuit) {
351 const auto bits = op->AffectedBits();
352
353 for (auto bit : bits) measQubits.insert(bit);
354 }
355
356 int creg_count = 0;
357 for (auto bit : measQubits) {
358 // this completion is needed to have a proper total cregister definition
359 // we need this to be able to address the bits properly, otherwise
360 // conversion circuit -> qasm -> circuit would not work properly
361 if (creg_count < static_cast<int>(bit))
362 qasm += "creg c" + std::to_string(creg_count) + "[" +
363 std::to_string(bit - creg_count) + "];\n";
364
365 qasm += "creg c" + std::to_string(bit) + "[1];\n";
366 creg_count = bit + 1;
367 }
368
369 return qasm;
370 }
371
372 static std::string QasmGatesAndRegsDefinitions(
373 const std::shared_ptr<Circuits::Circuit<Time>> &circuit) {
374 std::vector<bool> neededGates(static_cast<size_t>(QasmGateType::NoGate),
375 false);
376
377 // #define DONT_USE_HEADER_DEFINITIONS 1
378
379 for (const auto &op : circuit->GetOperations()) {
380 const auto opType = op->GetType();
381 if (opType == Circuits::OperationType::kGate ||
383 const auto &gate =
384 std::static_pointer_cast<Circuits::IQuantumGate<Time>>(
386 ? std::static_pointer_cast<
388 ->GetOperation()
389 : op);
390
391 switch (gate->GetGateType()) {
393#ifdef DONT_USE_HEADER_DEFINITIONS
394 neededGates[static_cast<size_t>(QasmGateType::U)] = true;
395#else
396 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
397#endif
398 break;
400#ifdef DONT_USE_HEADER_DEFINITIONS
401 neededGates[static_cast<size_t>(QasmGateType::X)] = true;
402#else
403 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
404#endif
405 break;
407#ifdef DONT_USE_HEADER_DEFINITIONS
408 neededGates[static_cast<size_t>(QasmGateType::Y)] = true;
409#else
410 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
411#endif
412 break;
414#ifdef DONT_USE_HEADER_DEFINITIONS
415 neededGates[static_cast<size_t>(QasmGateType::Z)] = true;
416#else
417 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
418#endif
419 break;
421#ifdef DONT_USE_HEADER_DEFINITIONS
422 neededGates[static_cast<size_t>(QasmGateType::H)] = true;
423#else
424 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
425#endif
426 break;
428#ifdef DONT_USE_HEADER_DEFINITIONS
429 neededGates[static_cast<size_t>(QasmGateType::S)] = true;
430#else
431 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
432#endif
433 break;
435#ifdef DONT_USE_HEADER_DEFINITIONS
436 neededGates[static_cast<size_t>(QasmGateType::SDG)] = true;
437#else
438 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
439#endif
440 break;
442#ifdef DONT_USE_HEADER_DEFINITIONS
443 neededGates[static_cast<size_t>(QasmGateType::T)] = true;
444#else
445 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
446#endif
447 break;
449#ifdef DONT_USE_HEADER_DEFINITIONS
450 neededGates[static_cast<size_t>(QasmGateType::TDG)] = true;
451#else
452 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
453#endif
454 break;
455
456 //*************************************************************************************************
457 // defined here, not in the 'standard' header
459 neededGates[static_cast<size_t>(QasmGateType::Sx)] = true;
460#ifndef DONT_USE_HEADER_DEFINITIONS
461 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
462#endif
463 break;
465 neededGates[static_cast<size_t>(QasmGateType::SxDG)] = true;
466#ifndef DONT_USE_HEADER_DEFINITIONS
467 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
468#endif
469 break;
471 neededGates[static_cast<size_t>(QasmGateType::K)] = true;
472#ifndef DONT_USE_HEADER_DEFINITIONS
473 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
474#endif
475 break;
476 //*************************************************************************************************
477
479#ifdef DONT_USE_HEADER_DEFINITIONS
480 neededGates[static_cast<size_t>(QasmGateType::Rx)] = true;
481#else
482 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
483#endif
484 break;
486#ifdef DONT_USE_HEADER_DEFINITIONS
487 neededGates[static_cast<size_t>(QasmGateType::Ry)] = true;
488#else
489 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
490#endif
491 break;
493#ifdef DONT_USE_HEADER_DEFINITIONS
494 neededGates[static_cast<size_t>(QasmGateType::Rz)] = true;
495#else
496 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
497#endif
498 break;
499
501#ifdef DONT_USE_HEADER_DEFINITIONS
502 neededGates[static_cast<size_t>(QasmGateType::U)] = true;
503#else
504 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
505#endif
506 break;
507
509 // standard gate
510#ifndef DONT_USE_HEADER_DEFINITIONS
511 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
512#endif
513 break;
515#ifdef DONT_USE_HEADER_DEFINITIONS
516 neededGates[static_cast<size_t>(QasmGateType::CY)] = true;
517 neededGates[static_cast<size_t>(QasmGateType::SDG)] = true;
518 neededGates[static_cast<size_t>(QasmGateType::S)] = true;
519#else
520 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
521#endif
522 break;
524#ifdef DONT_USE_HEADER_DEFINITIONS
525 neededGates[static_cast<size_t>(QasmGateType::CZ)] = true;
526 neededGates[static_cast<size_t>(QasmGateType::H)] = true;
527#else
528 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
529#endif
530 break;
532#ifdef DONT_USE_HEADER_DEFINITIONS
533 neededGates[static_cast<size_t>(QasmGateType::CU1)] = true;
534#else
535 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
536#endif
537 break;
538
539 //*************************************************************************************************
540 // defined here, not in the 'standard' header
542 neededGates[static_cast<size_t>(QasmGateType::CRX)] = true;
543#ifdef DONT_USE_HEADER_DEFINITIONS
544 neededGates[static_cast<size_t>(QasmGateType::CU3)] = true;
545#else
546 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
547#endif
548 break;
550 neededGates[static_cast<size_t>(QasmGateType::CRY)] = true;
551#ifdef DONT_USE_HEADER_DEFINITIONS
552 neededGates[static_cast<size_t>(QasmGateType::CU3)] = true;
553#else
554 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
555#endif
556 break;
557 //*************************************************************************************************
558
560#ifdef DONT_USE_HEADER_DEFINITIONS
561 neededGates[static_cast<size_t>(QasmGateType::CRZ)] = true;
562#else
563 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
564#endif
565 break;
567#ifdef DONT_USE_HEADER_DEFINITIONS
568 neededGates[static_cast<size_t>(QasmGateType::CH)] = true;
569 neededGates[static_cast<size_t>(QasmGateType::H)] = true;
570 neededGates[static_cast<size_t>(QasmGateType::SDG)] = true;
571 neededGates[static_cast<size_t>(QasmGateType::T)] = true;
572 neededGates[static_cast<size_t>(QasmGateType::S)] = true;
573 neededGates[static_cast<size_t>(QasmGateType::X)] = true;
574#else
575 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] = true;
576#endif
577 break;
578
579 //*************************************************************************************************
580 // defined here, not in the 'standard' header
582 neededGates[static_cast<size_t>(QasmGateType::CSX)] = true;
583 neededGates[static_cast<size_t>(QasmGateType::CS)] = true;
584 break;
586 neededGates[static_cast<size_t>(QasmGateType::CSXDAG)] = true;
587 neededGates[static_cast<size_t>(QasmGateType::CSDAG)] = true;
588 break;
589
590 // we have a problem with this, our CU is with 4 parameters, so not
591 // fully converted if the 4th parameter is not zero!
593 if (gate->GetParams()[3] == 0) {
594#ifdef DONT_USE_HEADER_DEFINITIONS
595 neededGates[static_cast<size_t>(QasmGateType::CU3)] = true;
596#else
597 neededGates[static_cast<size_t>(QasmGateType::IncludedGate)] =
598 true;
599#endif
600 } else
601 throw std::runtime_error(
602 "CU with gamma non zero not supported yet!");
603 break;
604 //*************************************************************************************************
605
606 // swap is converted to three CX gates
608 neededGates[static_cast<size_t>(QasmGateType::SWAP)] = true;
609 break;
610 // three qubit gates, do not need to be converted as they are
611 // converted to two qubit gates already
613 [[fallthrough]];
615 throw std::runtime_error("Not supported!");
616 break;
618 break;
619 }
620 }
621 }
622
623 std::string qasm;
624
625 if (neededGates[static_cast<size_t>(QasmGateType::IncludedGate)])
626 qasm += "include \"qelib1.inc\";\n";
627
628 qasm += QasmRegisters(circuit);
629
630 // WARNING: order matters, so be sure you won't define gates based on gates
631 // that are defined later here
632
633 if (neededGates[static_cast<size_t>(QasmGateType::X)])
634 qasm += XGateDefinition();
635 if (neededGates[static_cast<size_t>(QasmGateType::Y)])
636 qasm += YGateDefinition();
637 if (neededGates[static_cast<size_t>(QasmGateType::Z)])
638 qasm += ZGateDefinition();
639 if (neededGates[static_cast<size_t>(QasmGateType::H)])
640 qasm += HGateDefinition();
641 if (neededGates[static_cast<size_t>(QasmGateType::S)])
642 qasm += SGateDefinition();
643 if (neededGates[static_cast<size_t>(QasmGateType::SDG)])
644 qasm += SDGGateDefinition();
645
646 if (neededGates[static_cast<size_t>(QasmGateType::Sx)])
647 qasm += SxGateDefinition();
648 if (neededGates[static_cast<size_t>(QasmGateType::SxDG)])
649 qasm += SxDGGateDefinition();
650
651 if (neededGates[static_cast<size_t>(QasmGateType::K)])
652 qasm += KGateDefinition();
653
654 if (neededGates[static_cast<size_t>(QasmGateType::T)])
655 qasm += TGateDefinition();
656 if (neededGates[static_cast<size_t>(QasmGateType::TDG)])
657 qasm += TDGGateDefinition();
658
659 if (neededGates[static_cast<size_t>(QasmGateType::Rx)])
660 qasm += RxGateDefinition();
661 if (neededGates[static_cast<size_t>(QasmGateType::Ry)])
662 qasm += RyGateDefinition();
663 if (neededGates[static_cast<size_t>(QasmGateType::Rz)])
664 qasm += RzGateDefinition();
665
666 if (neededGates[static_cast<size_t>(QasmGateType::CZ)])
667 qasm += CZGateDefinition();
668 if (neededGates[static_cast<size_t>(QasmGateType::CY)])
669 qasm += CYGateDefinition();
670 if (neededGates[static_cast<size_t>(QasmGateType::CH)])
671 qasm += CHGateDefinition();
672 // qasm += CCXGateDefinition();
673
674 if (neededGates[static_cast<size_t>(QasmGateType::CRZ)])
675 qasm += CRZGateDefinition();
676 if (neededGates[static_cast<size_t>(QasmGateType::CU1)])
677 qasm += CU1GateDefinition();
678 if (neededGates[static_cast<size_t>(QasmGateType::CU3)])
679 qasm += CU3GateDefinition();
680 if (neededGates[static_cast<size_t>(QasmGateType::CRX)])
681 qasm += CRXGateDefinition();
682 if (neededGates[static_cast<size_t>(QasmGateType::CRY)])
683 qasm += CRYGateDefinition();
684 if (neededGates[static_cast<size_t>(QasmGateType::SWAP)])
685 qasm += SwapGateDefinition();
686
687 if (neededGates[static_cast<size_t>(QasmGateType::CS)])
688 qasm += CSGateDefinition();
689 if (neededGates[static_cast<size_t>(QasmGateType::CSDAG)])
690 qasm += CSDAGGateDefinition();
691
692 if (neededGates[static_cast<size_t>(QasmGateType::CSX)])
693 qasm += CSXGateDefinition();
694 if (neededGates[static_cast<size_t>(QasmGateType::CSXDAG)])
695 qasm += CSXDAGGateDefinition();
696
697 return qasm;
698 }
699
700 // gates definitions
701 static std::string U3GateDefinition() {
702 return "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }\n";
703 }
704
705 static std::string U2GateDefinition() {
706 return "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }\n";
707 }
708
709 static std::string U1GateDefinition() {
710 return "gate u1(lambda) q { U(0,0,lambda) q; }\n";
711 }
712
713 static std::string XGateDefinition() {
714 return "gate x a { U(pi,0,pi) a; }\n";
715 }
716
717 static std::string YGateDefinition() {
718 return "gate y a { U(pi,pi/2,pi/2) a; }\n";
719 }
720
721 static std::string ZGateDefinition() { return "gate z a { U(0,0,pi) a; }\n"; }
722
723 static std::string HGateDefinition() {
724 return "gate h a { U(pi/2,0,pi) a; }\n";
725 }
726
727 static std::string SGateDefinition() {
728 return "gate s a { U(0,0,pi/2) a; }\n";
729 }
730
731 static std::string SDGGateDefinition() {
732 return "gate sdg a { U(0,0,-pi/2) a; }\n";
733 }
734
735 // the following two introduce a global phase compared with the operators for
736 // sx and sxdg, but that should be ok
737 static std::string SxGateDefinition() {
738 return "gate sx a { U(pi/2,-pi/2,pi/2) a; }\n"; // this is a rotation,
739 // equivalent up to a
740 // global phase
741 }
742
743 static std::string SxDGGateDefinition() {
744 return "gate sxdg a { U(-pi/2,-pi/2,pi/2) a; }\n";
745 }
746
747 static std::string KGateDefinition() {
748 return "gate k a { U(pi/2,pi/2,pi/2) a; }\n";
749 }
750
751 static std::string TGateDefinition() {
752 return "gate t a { U(0,0,pi/4) a; }\n";
753 }
754
755 static std::string TDGGateDefinition() {
756 return "gate tdg a { U(0,0,-pi/4) a; }\n";
757 }
758
759 static std::string RxGateDefinition() {
760 return "gate rx(theta) a { U(theta,-pi/2,pi/2) a; }\n";
761 }
762
763 static std::string RyGateDefinition() {
764 return "gate ry(theta) a { U(theta,0,0) a; }\n";
765 }
766
767 static std::string RzGateDefinition() {
768 return "gate rz(phi) a { U(0,0,phi) a; }\n";
769 }
770
771 static std::string SwapGateDefinition() {
772 return "gate swap a,b { CX a,b; CX b,a; CX a,b; }\n";
773 }
774
775 // with hadamard it's going to the x basis... then after cx, back to the z
776 // basis, applying hadamard again
777 static std::string CZGateDefinition() {
778 return "gate cz a,b { h b; CX a,b; h b; }\n";
779 }
780
781 static std::string CYGateDefinition() {
782 return "gate cy a,b { sdg b; CX a,b; s b; }\n";
783 }
784
785 static std::string CHGateDefinition() {
786 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; "
787 "x b; s a; }\n";
788 }
789
790 static std::string CCXGateDefinition() {
791 return "gate ccx a,b,c\
792 {\
793 h c;\
794 cx b, c; tdg c;\
795 cx a, c; t c;\
796 cx b, c; tdg c;\
797 cx a, c; t b; t c; h c;\
798 cx a, b; t a; tdg b;\
799 cx a, b;\
800 }\n";
801 }
802
803 static std::string CU1GateDefinition() {
804 return "gate cu1(lambda) a,b { U(0,0,lambda/2) a; CX a,b; U(0,0,-lambda/2) "
805 "b; CX a,b; U(0,0,lambda/2) b; }\n";
806 }
807
808 static std::string CU3GateDefinition() {
809 return "gate cu3(theta,phi,lambda) c,t { U(0,0,(lambda+phi)/2) c; "
810 "U(0,0,(lambda-phi)/2) t; CX c,t; U(-theta/2,0,-(phi+lambda)/2) t; "
811 "CX c,t; U(theta/2,phi,0) t; }\n";
812 }
813
814 //*************************************************************************************************
815 // defined here, not in the 'standard' header
816
817 static std::string CRXGateDefinition() {
818 return "gate crx(theta) a,b { cu3(theta,-pi/2,pi/2) a,b; }\n";
819 }
820
821 static std::string CRYGateDefinition() {
822 return "gate cry(theta) a,b { cu3(theta,0,0) a,b; }\n";
823 }
824
825 static std::string CRZGateDefinition() {
826 return "gate crz(lambda) a,b { U(0,0,lambda/2) b; CX a,b; U(0,0,-lambda/2) "
827 "b; CX a,b; }\n";
828 }
829
830 static std::string CSGateDefinition() {
831 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) "
832 "t; CX c,t; }\n";
833 }
834
835 static std::string CSDAGGateDefinition() {
836 return "gate csdag c,t { CX c,t; U(0,0,pi/4) t; CX c,t; U(0,0,-pi/4) c; "
837 "U(0,0,-pi/4) t; }\n";
838 }
839
840 static std::string CSXGateDefinition() {
841 return "gate csx c,t { U(pi/2,0,pi) t; cs c,t; U(pi/2,0,pi) t; }\n";
842 }
843
844 static std::string CSXDAGGateDefinition() {
845 return "gate csxdag c,t { U(pi/2,0,pi) t; csdag c,t; U(pi/2,0,pi) t; }\n";
846 }
847};
848
849} // namespace qasm
850
851#endif
Circuit class for holding the sequence of operations.
Definition Circuit.h:46
An operation conditioned on classical values.
The operation interface.
Definition Operations.h:358
static std::string Generate(const std::shared_ptr< Circuits::Circuit< Time > > &circuit)
Definition CircQasm.h:81
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:64
@ kConditionalGate
conditional gate, similar with gate, but conditioned on something from 'OperationState'
@ kNoOp
no operation, just a placeholder, could be used to erase some operation from a circuit
@ kComposite
a composite operation, contains other operations - should not be used in the beginning,...
@ kRandomGen
random classical bit generator, result in 'OperationState'
@ kConditionalRandomGen
conditional random generator, similar with random gen, but conditioned on something from 'OperationSt...
@ kConditionalMeasurement
conditional measurement, similar with measurement, but conditioned on something from 'OperationState'
@ kMeasurement
measurement, result in 'OperationState'
@ kGate
the usual quantum gate, result stays in simulator's state
@ kReset
reset, no result in 'state', just apply measurement, then apply not on all qubits that were measured ...