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));
71 return GenerateFromCircuit(mappedCircuit,
false);
83 return GenerateFromCircuit(circuit,
true);
87 static std::string GenerateFromCircuit(
89 if (circuit->empty())
return "";
92 (clone ? std::static_pointer_cast<Circuits::Circuit<Time>>(
96 circ->ConvertForDistribution();
98 std::string
qasm = QasmHeader();
100 qasm += QasmGatesAndRegsDefinitions(circ);
103 for (
const auto &gate : circ->GetOperations())
104 qasm += OperationToQasm(gate);
109 static std::string OperationToQasm(
113 switch (operation->GetType()) {
115 qasm += GateToQasm(operation);
118 auto qbits = operation->AffectedQubits();
119 auto bits = operation->AffectedBits();
121 assert(qbits.size() == bits.size());
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";
128 auto qbits = operation->AffectedQubits();
129 for (
const auto &qbit : qbits)
130 qasm +=
"reset q[" + std::to_string(qbit) +
"];\n";
139 std::static_pointer_cast<Circuits::IConditionalOperation<Time>>(
141 auto bits = condop->AffectedBits();
142 auto vals = std::static_pointer_cast<Circuits::EqualCondition>(
143 condop->GetCondition())
145 assert(bits.size() == vals.size());
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) +
") ";
151 const auto theop = condop->GetOperation();
152 qasm += OperationToQasm(theop);
156 qasm +=
"barrier q;\n";
163 throw std::runtime_error(
"Not supported!");
170 static std::string GateToQasm(
176 std::static_pointer_cast<Circuits::IQuantumGate<Time>>(operation);
180 switch (gate->GetGateType()) {
182 qasm +=
"U(0,0," + std::to_string(gate->GetParams()[0]) +
") q[" +
183 std::to_string(gate->GetQubit(0)) +
"];\n";
186 qasm +=
"x q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
189 qasm +=
"y q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
192 qasm +=
"z q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
195 qasm +=
"h q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
198 qasm +=
"s q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
201 qasm +=
"sdg q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
204 qasm +=
"t q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
207 qasm +=
"tdg q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
213 qasm +=
"sx q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
216 qasm +=
"sxdg q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
219 qasm +=
"k q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
224 qasm +=
"rx(" + std::to_string(gate->GetParams()[0]) +
") q[" +
225 std::to_string(gate->GetQubit(0)) +
"];\n";
228 qasm +=
"ry(" + std::to_string(gate->GetParams()[0]) +
") q[" +
229 std::to_string(gate->GetQubit(0)) +
"];\n";
232 qasm +=
"rz(" + std::to_string(gate->GetParams()[0]) +
") q[" +
233 std::to_string(gate->GetQubit(0)) +
"];\n";
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";
242 throw std::runtime_error(
"U with gamma non zero not supported yet!");
247 qasm +=
"CX q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
248 std::to_string(gate->GetQubit(1)) +
"];\n";
251 qasm +=
"cy q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
252 std::to_string(gate->GetQubit(1)) +
"];\n";
255 qasm +=
"cz q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
256 std::to_string(gate->GetQubit(1)) +
"];\n";
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";
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";
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";
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";
284 qasm +=
"ch q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
285 std::to_string(gate->GetQubit(1)) +
"];\n";
291 qasm +=
"csx q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
292 std::to_string(gate->GetQubit(1)) +
"];\n";
295 qasm +=
"csxdag q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
296 std::to_string(gate->GetQubit(1)) +
"];\n";
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";
309 throw std::runtime_error(
"CU with gamma non zero not supported yet!");
315 qasm +=
"swap q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
316 std::to_string(gate->GetQubit(1)) +
"];\n";
323 throw std::runtime_error(
"Not supported!");
332 static std::string QasmHeader() {
333 std::string
qasm =
"OPENQASM 2.0;\n";
340 static std::string QasmRegisters(
342 const auto nrq = circuit->GetMaxQubitIndex() + 1;
344 const std::string nrq_str = std::to_string(nrq);
346 std::string
qasm =
"qreg q[" + nrq_str +
"];\n";
348 std::set<size_t> measQubits;
350 for (
const auto &op : *circuit) {
351 const auto bits = op->AffectedBits();
353 for (
auto bit : bits) measQubits.insert(bit);
357 for (
auto bit : measQubits) {
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";
365 qasm +=
"creg c" + std::to_string(bit) +
"[1];\n";
366 creg_count = bit + 1;
372 static std::string QasmGatesAndRegsDefinitions(
379 for (
const auto &op : circuit->GetOperations()) {
380 const auto opType = op->GetType();
384 std::static_pointer_cast<Circuits::IQuantumGate<Time>>(
386 ? std::static_pointer_cast<
391 switch (gate->GetGateType()) {
393#ifdef DONT_USE_HEADER_DEFINITIONS
400#ifdef DONT_USE_HEADER_DEFINITIONS
407#ifdef DONT_USE_HEADER_DEFINITIONS
414#ifdef DONT_USE_HEADER_DEFINITIONS
421#ifdef DONT_USE_HEADER_DEFINITIONS
428#ifdef DONT_USE_HEADER_DEFINITIONS
435#ifdef DONT_USE_HEADER_DEFINITIONS
442#ifdef DONT_USE_HEADER_DEFINITIONS
449#ifdef DONT_USE_HEADER_DEFINITIONS
460#ifndef DONT_USE_HEADER_DEFINITIONS
466#ifndef DONT_USE_HEADER_DEFINITIONS
472#ifndef DONT_USE_HEADER_DEFINITIONS
479#ifdef DONT_USE_HEADER_DEFINITIONS
486#ifdef DONT_USE_HEADER_DEFINITIONS
493#ifdef DONT_USE_HEADER_DEFINITIONS
501#ifdef DONT_USE_HEADER_DEFINITIONS
510#ifndef DONT_USE_HEADER_DEFINITIONS
515#ifdef DONT_USE_HEADER_DEFINITIONS
524#ifdef DONT_USE_HEADER_DEFINITIONS
532#ifdef DONT_USE_HEADER_DEFINITIONS
543#ifdef DONT_USE_HEADER_DEFINITIONS
551#ifdef DONT_USE_HEADER_DEFINITIONS
560#ifdef DONT_USE_HEADER_DEFINITIONS
567#ifdef DONT_USE_HEADER_DEFINITIONS
593 if (gate->GetParams()[3] == 0) {
594#ifdef DONT_USE_HEADER_DEFINITIONS
601 throw std::runtime_error(
602 "CU with gamma non zero not supported yet!");
615 throw std::runtime_error(
"Not supported!");
626 qasm +=
"include \"qelib1.inc\";\n";
628 qasm += QasmRegisters(circuit);
634 qasm += XGateDefinition();
636 qasm += YGateDefinition();
638 qasm += ZGateDefinition();
640 qasm += HGateDefinition();
642 qasm += SGateDefinition();
644 qasm += SDGGateDefinition();
647 qasm += SxGateDefinition();
649 qasm += SxDGGateDefinition();
652 qasm += KGateDefinition();
655 qasm += TGateDefinition();
657 qasm += TDGGateDefinition();
660 qasm += RxGateDefinition();
662 qasm += RyGateDefinition();
664 qasm += RzGateDefinition();
667 qasm += CZGateDefinition();
669 qasm += CYGateDefinition();
671 qasm += CHGateDefinition();
675 qasm += CRZGateDefinition();
677 qasm += CU1GateDefinition();
679 qasm += CU3GateDefinition();
681 qasm += CRXGateDefinition();
683 qasm += CRYGateDefinition();
685 qasm += SwapGateDefinition();
688 qasm += CSGateDefinition();
690 qasm += CSDAGGateDefinition();
693 qasm += CSXGateDefinition();
695 qasm += CSXDAGGateDefinition();
701 static std::string U3GateDefinition() {
702 return "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }\n";
705 static std::string U2GateDefinition() {
706 return "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }\n";
709 static std::string U1GateDefinition() {
710 return "gate u1(lambda) q { U(0,0,lambda) q; }\n";
713 static std::string XGateDefinition() {
714 return "gate x a { U(pi,0,pi) a; }\n";
717 static std::string YGateDefinition() {
718 return "gate y a { U(pi,pi/2,pi/2) a; }\n";
721 static std::string ZGateDefinition() {
return "gate z a { U(0,0,pi) a; }\n"; }
723 static std::string HGateDefinition() {
724 return "gate h a { U(pi/2,0,pi) a; }\n";
727 static std::string SGateDefinition() {
728 return "gate s a { U(0,0,pi/2) a; }\n";
731 static std::string SDGGateDefinition() {
732 return "gate sdg a { U(0,0,-pi/2) a; }\n";
737 static std::string SxGateDefinition() {
738 return "gate sx a { U(pi/2,-pi/2,pi/2) a; }\n";
743 static std::string SxDGGateDefinition() {
744 return "gate sxdg a { U(-pi/2,-pi/2,pi/2) a; }\n";
747 static std::string KGateDefinition() {
748 return "gate k a { U(pi/2,pi/2,pi/2) a; }\n";
751 static std::string TGateDefinition() {
752 return "gate t a { U(0,0,pi/4) a; }\n";
755 static std::string TDGGateDefinition() {
756 return "gate tdg a { U(0,0,-pi/4) a; }\n";
759 static std::string RxGateDefinition() {
760 return "gate rx(theta) a { U(theta,-pi/2,pi/2) a; }\n";
763 static std::string RyGateDefinition() {
764 return "gate ry(theta) a { U(theta,0,0) a; }\n";
767 static std::string RzGateDefinition() {
768 return "gate rz(phi) a { U(0,0,phi) a; }\n";
771 static std::string SwapGateDefinition() {
772 return "gate swap a,b { CX a,b; CX b,a; CX a,b; }\n";
777 static std::string CZGateDefinition() {
778 return "gate cz a,b { h b; CX a,b; h b; }\n";
781 static std::string CYGateDefinition() {
782 return "gate cy a,b { sdg b; CX a,b; s b; }\n";
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; "
790 static std::string CCXGateDefinition() {
791 return "gate ccx a,b,c\
797 cx a, c; t b; t c; h c;\
798 cx a, b; t a; tdg b;\
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";
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";
817 static std::string CRXGateDefinition() {
818 return "gate crx(theta) a,b { cu3(theta,-pi/2,pi/2) a,b; }\n";
821 static std::string CRYGateDefinition() {
822 return "gate cry(theta) a,b { cu3(theta,0,0) a,b; }\n";
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) "
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) "
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";
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";
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";