71 const std::unordered_map<Types::qubit_t, Types::qubit_t> &bitsMap,
73 const auto mappedCircuit =
74 std::static_pointer_cast<Circuits::Circuit<Time>>(
75 circuit->Remap(bitsMap, bitsMap));
77 return GenerateFromCircuit(mappedCircuit,
false, version);
90 return GenerateFromCircuit(circuit,
true, version);
94 static std::string GenerateFromCircuit(
97 if (circuit->empty())
return "";
100 (clone ? std::static_pointer_cast<Circuits::Circuit<Time>>(
104 circ->ConvertForDistribution();
106 std::string
qasm = QasmHeader(version);
108 qasm += QasmGatesAndRegsDefinitions(circ, version);
111 for (
const auto &gate : circ->GetOperations())
112 qasm += OperationToQasm(gate, version);
117 static std::string OperationToQasm(
122 switch (operation->GetType()) {
124 qasm += GateToQasm(operation, version);
127 auto qbits = operation->AffectedQubits();
128 auto bits = operation->AffectedBits();
130 assert(qbits.size() == bits.size());
132 for (
size_t i = 0; i < qbits.size(); ++i)
134 ?
"c" + std::to_string(bits[i]) +
"[0] = measure q[" +
135 std::to_string(qbits[i]) +
"];\n"
136 :
"measure q[" + std::to_string(qbits[i]) +
"]->c" +
137 std::to_string(bits[i]) +
"[0];\n";
140 auto qbits = operation->AffectedQubits();
141 for (
const auto &qbit : qbits)
142 qasm +=
"reset q[" + std::to_string(qbit) +
"];\n";
151 std::static_pointer_cast<Circuits::IConditionalOperation<Time>>(
153 auto bits = condop->AffectedBits();
154 auto vals = std::static_pointer_cast<Circuits::EqualCondition>(
155 condop->GetCondition())
157 assert(bits.size() == vals.size());
159 const auto theop = condop->GetOperation();
162 for (
size_t i = 0; i < bits.size(); ++i) {
163 if (i != 0) qasm +=
" && ";
164 if (!vals[i]) qasm +=
"!";
165 qasm +=
"c" + std::to_string(bits[i]) +
"[0]";
169 const std::string body = OperationToQasm(theop, version);
170 size_t lineStart = 0;
171 while (lineStart < body.size()) {
172 const size_t lineEnd = body.find(
'\n', lineStart);
173 qasm +=
" " + body.substr(lineStart, lineEnd - lineStart) +
"\n";
174 if (lineEnd == std::string::npos)
break;
175 lineStart = lineEnd + 1;
179 for (
size_t i = 0; i < bits.size(); ++i)
180 qasm +=
"if(c" + std::to_string(bits[i]) +
181 "==" + std::to_string(vals[i] ? 1 : 0) +
") ";
182 qasm += OperationToQasm(theop, version);
187 qasm +=
"barrier q;\n";
191 std::static_pointer_cast<Circuits::Delay<Time>>(operation);
192 auto qbit = delayOp->GetQubit();
193 auto dur = delayOp->GetDuration();
195 qasm +=
"delay[" + std::to_string(dur) +
"s] q[" +
196 std::to_string(qbit) +
"];\n";
198 qasm +=
"delay(" + std::to_string(dur) +
") q[" +
199 std::to_string(qbit) +
"];\n";
209 throw std::runtime_error(
"Not supported!");
216 static std::string GateToQasm(
217 const std::shared_ptr<Circuits::IOperation<Time>> &operation,
223 std::static_pointer_cast<Circuits::IQuantumGate<Time>>(operation);
227 switch (gate->GetGateType()) {
229 qasm +=
"U(0,0," + std::to_string(gate->GetParams()[0]) +
") q[" +
230 std::to_string(gate->GetQubit(0)) +
"];\n";
233 qasm +=
"x q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
236 qasm +=
"y q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
239 qasm +=
"z q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
242 qasm +=
"h q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
245 qasm +=
"s q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
248 qasm +=
"sdg q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
251 qasm +=
"t q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
254 qasm +=
"tdg q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
260 qasm +=
"sx q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
263 qasm +=
"sxdg q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
266 qasm +=
"k q[" + std::to_string(gate->GetQubit(0)) +
"];\n";
271 qasm +=
"rx(" + std::to_string(gate->GetParams()[0]) +
") q[" +
272 std::to_string(gate->GetQubit(0)) +
"];\n";
275 qasm +=
"ry(" + std::to_string(gate->GetParams()[0]) +
") q[" +
276 std::to_string(gate->GetQubit(0)) +
"];\n";
279 qasm +=
"rz(" + std::to_string(gate->GetParams()[0]) +
") q[" +
280 std::to_string(gate->GetQubit(0)) +
"];\n";
283 if (gate->GetParams()[3] == 0)
284 qasm +=
"U(" + std::to_string(gate->GetParams()[0]) +
"," +
285 std::to_string(gate->GetParams()[1]) +
"," +
286 std::to_string(gate->GetParams()[2]) +
") q[" +
287 std::to_string(gate->GetQubit(0)) +
"];\n";
289 throw std::runtime_error(
"U with gamma non zero not supported yet!");
294 qasm +=
"CX q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
295 std::to_string(gate->GetQubit(1)) +
"];\n";
298 qasm +=
"cy q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
299 std::to_string(gate->GetQubit(1)) +
"];\n";
302 qasm +=
"cz q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
303 std::to_string(gate->GetQubit(1)) +
"];\n";
307 std::to_string(gate->GetParams()[0]) +
") q[" +
308 std::to_string(gate->GetQubit(0)) +
"],q[" +
309 std::to_string(gate->GetQubit(1)) +
"];\n";
315 qasm +=
"crx(" + std::to_string(gate->GetParams()[0]) +
") q[" +
316 std::to_string(gate->GetQubit(0)) +
"],q[" +
317 std::to_string(gate->GetQubit(1)) +
"];\n";
320 qasm +=
"cry(" + std::to_string(gate->GetParams()[0]) +
") q[" +
321 std::to_string(gate->GetQubit(0)) +
"],q[" +
322 std::to_string(gate->GetQubit(1)) +
"];\n";
327 qasm +=
"crz(" + std::to_string(gate->GetParams()[0]) +
") q[" +
328 std::to_string(gate->GetQubit(0)) +
"],q[" +
329 std::to_string(gate->GetQubit(1)) +
"];\n";
332 qasm +=
"ch q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
333 std::to_string(gate->GetQubit(1)) +
"];\n";
339 qasm +=
"csx q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
340 std::to_string(gate->GetQubit(1)) +
"];\n";
343 qasm +=
"csxdag q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
344 std::to_string(gate->GetQubit(1)) +
"];\n";
351 qasm +=
"cu(" + std::to_string(gate->GetParams()[0]) +
"," +
352 std::to_string(gate->GetParams()[1]) +
"," +
353 std::to_string(gate->GetParams()[2]) +
"," +
354 std::to_string(gate->GetParams()[3]) +
") q[" +
355 std::to_string(gate->GetQubit(0)) +
"], q[" +
356 std::to_string(gate->GetQubit(1)) +
"];\n";
357 else if (gate->GetParams()[3] == 0)
358 qasm +=
"cu3(" + std::to_string(gate->GetParams()[0]) +
"," +
359 std::to_string(gate->GetParams()[1]) +
"," +
360 std::to_string(gate->GetParams()[2]) +
") q[" +
361 std::to_string(gate->GetQubit(0)) +
"], q[" +
362 std::to_string(gate->GetQubit(1)) +
"];\n";
364 throw std::runtime_error(
"CU with gamma non zero not supported yet!");
370 qasm +=
"swap q[" + std::to_string(gate->GetQubit(0)) +
"],q[" +
371 std::to_string(gate->GetQubit(1)) +
"];\n";
378 throw std::runtime_error(
"Not supported!");
396 static std::string QasmRegisters(
397 const std::shared_ptr<Circuits::Circuit<Time>> &circuit,
399 const auto nrq = circuit->GetMaxQubitIndex() + 1;
401 const std::string nrq_str = std::to_string(nrq);
404 ?
"qubit[" + nrq_str +
"] q;\n"
405 :
"qreg q[" + nrq_str +
"];\n";
407 std::set<size_t> measQubits;
409 for (
const auto &op : *circuit) {
410 std::vector<std::shared_ptr<Circuits::IOperation<Time>>> pending{op};
411 while (!pending.empty()) {
412 const auto current = pending.back();
415 for (
const auto bit : current->AffectedBits()) measQubits.insert(bit);
418 current->GetType() ==
421 std::static_pointer_cast<Circuits::IConditionalOperation<Time>>(
429 for (
auto bit : measQubits) {
433 if (creg_count <
static_cast<int>(bit)) {
434 const std::string fillerSize = std::to_string(bit - creg_count);
436 ?
"bit[" + fillerSize +
"] c" + std::to_string(creg_count) +
438 :
"creg c" + std::to_string(creg_count) +
"[" + fillerSize +
443 ?
"bit[1] c" + std::to_string(bit) +
";\n"
444 :
"creg c" + std::to_string(bit) +
"[1];\n";
445 creg_count =
static_cast<int>(bit) + 1;
451 static std::string QasmGatesAndRegsDefinitions(
452 const std::shared_ptr<Circuits::Circuit<Time>> &circuit,
459 for (
const auto &op : circuit->GetOperations()) {
460 const auto opType = op->GetType();
464 std::static_pointer_cast<Circuits::IQuantumGate<Time>>(
466 ? std::static_pointer_cast<
467 Circuits::IConditionalOperation<Time>>(op)
471 switch (gate->GetGateType()) {
473#ifdef DONT_USE_HEADER_DEFINITIONS
480#ifdef DONT_USE_HEADER_DEFINITIONS
487#ifdef DONT_USE_HEADER_DEFINITIONS
494#ifdef DONT_USE_HEADER_DEFINITIONS
501#ifdef DONT_USE_HEADER_DEFINITIONS
508#ifdef DONT_USE_HEADER_DEFINITIONS
515#ifdef DONT_USE_HEADER_DEFINITIONS
522#ifdef DONT_USE_HEADER_DEFINITIONS
529#ifdef DONT_USE_HEADER_DEFINITIONS
539#ifdef DONT_USE_HEADER_DEFINITIONS
550#ifndef DONT_USE_HEADER_DEFINITIONS
556#ifndef DONT_USE_HEADER_DEFINITIONS
563#ifdef DONT_USE_HEADER_DEFINITIONS
570#ifdef DONT_USE_HEADER_DEFINITIONS
577#ifdef DONT_USE_HEADER_DEFINITIONS
585#ifdef DONT_USE_HEADER_DEFINITIONS
594#ifndef DONT_USE_HEADER_DEFINITIONS
599#ifdef DONT_USE_HEADER_DEFINITIONS
608#ifdef DONT_USE_HEADER_DEFINITIONS
616#ifdef DONT_USE_HEADER_DEFINITIONS
626#ifdef DONT_USE_HEADER_DEFINITIONS
636#ifdef DONT_USE_HEADER_DEFINITIONS
648#ifdef DONT_USE_HEADER_DEFINITIONS
655#ifdef DONT_USE_HEADER_DEFINITIONS
684 }
else if (gate->GetParams()[3] == 0) {
685#ifdef DONT_USE_HEADER_DEFINITIONS
692 throw std::runtime_error(
693 "CU with gamma non zero not supported yet!");
706 throw std::runtime_error(
"Not supported!");
718 :
"include \"qelib1.inc\";\n";
720 qasm += QasmRegisters(circuit, version);
726 qasm += XGateDefinition();
728 qasm += YGateDefinition();
730 qasm += ZGateDefinition();
732 qasm += HGateDefinition();
734 qasm += SGateDefinition();
736 qasm += SDGGateDefinition();
739 qasm += SxGateDefinition();
741 qasm += SxDGGateDefinition();
744 qasm += KGateDefinition();
747 qasm += TGateDefinition();
749 qasm += TDGGateDefinition();
752 qasm += RxGateDefinition();
754 qasm += RyGateDefinition();
756 qasm += RzGateDefinition();
759 qasm += CZGateDefinition();
761 qasm += CYGateDefinition();
763 qasm += CHGateDefinition();
767 qasm += CRZGateDefinition();
769 qasm += CU1GateDefinition();
771 qasm += CU3GateDefinition();
773 qasm += CRXGateDefinition();
775 qasm += CRYGateDefinition();
777 qasm += SwapGateDefinition();
780 qasm += CSGateDefinition();
782 qasm += CSDAGGateDefinition();
785 qasm += CSXGateDefinition();
787 qasm += CSXDAGGateDefinition();
793 static std::string U3GateDefinition() {
794 return "gate u3(theta,phi,lambda) q { U(theta,phi,lambda) q; }\n";
797 static std::string U2GateDefinition() {
798 return "gate u2(phi,lambda) q { U(pi/2,phi,lambda) q; }\n";
801 static std::string U1GateDefinition() {
802 return "gate u1(lambda) q { U(0,0,lambda) q; }\n";
805 static std::string XGateDefinition() {
806 return "gate x a { U(pi,0,pi) a; }\n";
809 static std::string YGateDefinition() {
810 return "gate y a { U(pi,pi/2,pi/2) a; }\n";
813 static std::string ZGateDefinition() {
return "gate z a { U(0,0,pi) a; }\n"; }
815 static std::string HGateDefinition() {
816 return "gate h a { U(pi/2,0,pi) a; }\n";
819 static std::string SGateDefinition() {
820 return "gate s a { U(0,0,pi/2) a; }\n";
823 static std::string SDGGateDefinition() {
824 return "gate sdg a { U(0,0,-pi/2) a; }\n";
829 static std::string SxGateDefinition() {
830 return "gate sx a { U(pi/2,-pi/2,pi/2) a; }\n";
835 static std::string SxDGGateDefinition() {
836 return "gate sxdg a { U(-pi/2,-pi/2,pi/2) a; }\n";
839 static std::string KGateDefinition() {
840 return "gate k a { U(pi/2,pi/2,pi/2) a; }\n";
843 static std::string TGateDefinition() {
844 return "gate t a { U(0,0,pi/4) a; }\n";
847 static std::string TDGGateDefinition() {
848 return "gate tdg a { U(0,0,-pi/4) a; }\n";
851 static std::string RxGateDefinition() {
852 return "gate rx(theta) a { U(theta,-pi/2,pi/2) a; }\n";
855 static std::string RyGateDefinition() {
856 return "gate ry(theta) a { U(theta,0,0) a; }\n";
859 static std::string RzGateDefinition() {
860 return "gate rz(phi) a { U(0,0,phi) a; }\n";
863 static std::string SwapGateDefinition() {
864 return "gate swap a,b { CX a,b; CX b,a; CX a,b; }\n";
869 static std::string CZGateDefinition() {
870 return "gate cz a,b { h b; CX a,b; h b; }\n";
873 static std::string CYGateDefinition() {
874 return "gate cy a,b { sdg b; CX a,b; s b; }\n";
877 static std::string CHGateDefinition() {
878 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; "
882 static std::string CCXGateDefinition() {
883 return "gate ccx a,b,c\
889 cx a, c; t b; t c; h c;\
890 cx a, b; t a; tdg b;\
895 static std::string CU1GateDefinition() {
896 return "gate cu1(lambda) a,b { U(0,0,lambda/2) a; CX a,b; U(0,0,-lambda/2) "
897 "b; CX a,b; U(0,0,lambda/2) b; }\n";
900 static std::string CU3GateDefinition() {
901 return "gate cu3(theta,phi,lambda) c,t { U(0,0,(lambda+phi)/2) c; "
902 "U(0,0,(lambda-phi)/2) t; CX c,t; U(-theta/2,0,-(phi+lambda)/2) t; "
903 "CX c,t; U(theta/2,phi,0) t; }\n";
909 static std::string CRXGateDefinition() {
910 return "gate crx(theta) a,b { cu3(theta,-pi/2,pi/2) a,b; }\n";
913 static std::string CRYGateDefinition() {
914 return "gate cry(theta) a,b { cu3(theta,0,0) a,b; }\n";
917 static std::string CRZGateDefinition() {
918 return "gate crz(lambda) a,b { U(0,0,lambda/2) b; CX a,b; U(0,0,-lambda/2) "
922 static std::string CSGateDefinition() {
923 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) "
927 static std::string CSDAGGateDefinition() {
928 return "gate csdag c,t { CX c,t; U(0,0,pi/4) t; CX c,t; U(0,0,-pi/4) c; "
929 "U(0,0,-pi/4) t; }\n";
932 static std::string CSXGateDefinition() {
933 return "gate csx c,t { U(pi/2,0,pi) t; cs c,t; U(pi/2,0,pi) t; }\n";
936 static std::string CSXDAGGateDefinition() {
937 return "gate csxdag c,t { U(pi/2,0,pi) t; csdag c,t; U(pi/2,0,pi) t; }\n";