Skip to content

Commit 87a6da8

Browse files
committed
Remove to_qasm3 function from circuit definition file
1 parent 91f4b5d commit 87a6da8

2 files changed

Lines changed: 2184 additions & 2010 deletions

File tree

src/circuit/qasm3_exporter.hpp

Lines changed: 361 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
2+
std::string to_qasm3(void) {
3+
add_pending_control_flow_op();
4+
5+
std::stringstream qasm3;
6+
qasm3 << std::setprecision(18);
7+
qasm3 << "OPENQASM 3.0;" << std::endl;
8+
qasm3 << "include \"stdgates.inc\";" << std::endl;
9+
10+
auto name_map = get_standard_gate_name_mapping();
11+
// add header for non-standard gates
12+
bool cs = false;
13+
bool sxdg = false;
14+
QkOpCounts opcounts = qk_circuit_count_ops(rust_circuit_.get());
15+
for (int i = 0; i < opcounts.len; i++) {
16+
if (opcounts.data[i].count != 0) {
17+
auto op = name_map[opcounts.data[i].name].gate_map();
18+
switch (op) {
19+
case QkGate_R:
20+
qasm3 << "gate r(p0, p1) _gate_q_0 {" << std::endl;
21+
qasm3 << " U(p0, -pi/2 + p1, pi/2 - p1) _gate_q_0;" << std::endl;
22+
qasm3 << "}" << std::endl;
23+
break;
24+
case QkGate_SXdg:
25+
case QkGate_RYY:
26+
case QkGate_XXPlusYY:
27+
case QkGate_XXMinusYY:
28+
if (!sxdg) {
29+
qasm3 << "gate sxdg _gate_q_0 {" << std::endl;
30+
qasm3 << " s _gate_q_0;" << std::endl;
31+
qasm3 << " h _gate_q_0;" << std::endl;
32+
qasm3 << " s _gate_q_0;" << std::endl;
33+
qasm3 << "}" << std::endl;
34+
sxdg = true;
35+
}
36+
if (op == QkGate_RYY) {
37+
qasm3 << "gate ryy(p0) _gate_q_0, _gate_q_1 {" << std::endl;
38+
qasm3 << " sxdg _gate_q_0;" << std::endl;
39+
qasm3 << " sxdg _gate_q_1;" << std::endl;
40+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
41+
qasm3 << " rz(p0) _gate_q_1;" << std::endl;
42+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
43+
qasm3 << " sx _gate_q_0;" << std::endl;
44+
qasm3 << " sx _gate_q_1;" << std::endl;
45+
qasm3 << "}" << std::endl;
46+
}
47+
if (op == QkGate_XXPlusYY) {
48+
qasm3 << "gate xx_plus_yy(p0, p1) _gate_q_0, _gate_q_1 {"
49+
<< std::endl;
50+
qasm3 << " rz(p1) _gate_q_0;" << std::endl;
51+
qasm3 << " sdg _gate_q_1;" << std::endl;
52+
qasm3 << " sx _gate_q_1;" << std::endl;
53+
qasm3 << " s _gate_q_1;" << std::endl;
54+
qasm3 << " s _gate_q_0;" << std::endl;
55+
qasm3 << " cx _gate_q_1, _gate_q_0;" << std::endl;
56+
qasm3 << " ry((-0.5)*p0) _gate_q_1;" << std::endl;
57+
qasm3 << " ry((-0.5)*p0) _gate_q_0;" << std::endl;
58+
qasm3 << " cx _gate_q_1, _gate_q_0;" << std::endl;
59+
qasm3 << " sdg _gate_q_0;" << std::endl;
60+
qasm3 << " sdg _gate_q_1;" << std::endl;
61+
qasm3 << " sxdg _gate_q_1;" << std::endl;
62+
qasm3 << " s _gate_q_1;" << std::endl;
63+
qasm3 << " rz(-p1) _gate_q_0;" << std::endl;
64+
qasm3 << "}" << std::endl;
65+
}
66+
if (op == QkGate_XXMinusYY) {
67+
qasm3 << "gate xx_minus_yy(p0, p1) _gate_q_0, _gate_q_1 {"
68+
<< std::endl;
69+
qasm3 << " rz(-p1) _gate_q_1;" << std::endl;
70+
qasm3 << " sdg _gate_q_0;" << std::endl;
71+
qasm3 << " sx _gate_q_0;" << std::endl;
72+
qasm3 << " s _gate_q_0;" << std::endl;
73+
qasm3 << " s _gate_q_1;" << std::endl;
74+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
75+
qasm3 << " ry(0.5*p0) _gate_q_0;" << std::endl;
76+
qasm3 << " ry((-0.5)*p0) _gate_q_1;" << std::endl;
77+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
78+
qasm3 << " sdg _gate_q_1;" << std::endl;
79+
qasm3 << " sdg _gate_q_0;" << std::endl;
80+
qasm3 << " sxdg _gate_q_0;" << std::endl;
81+
qasm3 << " s _gate_q_0;" << std::endl;
82+
qasm3 << " rz(p1) _gate_q_1;" << std::endl;
83+
qasm3 << "}" << std::endl;
84+
}
85+
break;
86+
case QkGate_DCX:
87+
qasm3 << "gate dcx _gate_q_0, _gate_q_1 {" << std::endl;
88+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
89+
qasm3 << " cx _gate_q_1, _gate_q_0;" << std::endl;
90+
qasm3 << "}" << std::endl;
91+
break;
92+
case QkGate_ECR:
93+
qasm3 << "gate ecr _gate_q_0, _gate_q_1 {" << std::endl;
94+
qasm3 << " s _gate_q_0;" << std::endl;
95+
qasm3 << " sx _gate_q_1;" << std::endl;
96+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
97+
qasm3 << " x _gate_q_0;" << std::endl;
98+
qasm3 << "}" << std::endl;
99+
break;
100+
case QkGate_ISwap:
101+
qasm3 << "gate iswap _gate_q_0, _gate_q_1 {" << std::endl;
102+
qasm3 << " s _gate_q_0;" << std::endl;
103+
qasm3 << " s _gate_q_1;" << std::endl;
104+
qasm3 << " h _gate_q_0;" << std::endl;
105+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
106+
qasm3 << " cx _gate_q_1, _gate_q_0;" << std::endl;
107+
qasm3 << " h _gate_q_1;" << std::endl;
108+
qasm3 << "}" << std::endl;
109+
break;
110+
case QkGate_CSX:
111+
case QkGate_CS:
112+
if (!cs) {
113+
qasm3 << "gate cs _gate_q_0, _gate_q_1 {" << std::endl;
114+
qasm3 << " t _gate_q_0;" << std::endl;
115+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
116+
qasm3 << " tdg _gate_q_1;" << std::endl;
117+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
118+
qasm3 << " t _gate_q_1;" << std::endl;
119+
qasm3 << "}" << std::endl;
120+
cs = true;
121+
}
122+
if (op == QkGate_CSX) {
123+
qasm3 << "gate csx _gate_q_0, _gate_q_1 {" << std::endl;
124+
qasm3 << " h _gate_q_1;" << std::endl;
125+
qasm3 << " cs _gate_q_0, _gate_q_1;" << std::endl;
126+
qasm3 << " h _gate_q_1;" << std::endl;
127+
qasm3 << "}" << std::endl;
128+
}
129+
break;
130+
case QkGate_CSdg:
131+
qasm3 << "gate csdg _gate_q_0, _gate_q_1 {" << std::endl;
132+
qasm3 << " tdg _gate_q_0;" << std::endl;
133+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
134+
qasm3 << " t _gate_q_1;" << std::endl;
135+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
136+
qasm3 << " tdg _gate_q_1;" << std::endl;
137+
qasm3 << "}" << std::endl;
138+
break;
139+
case QkGate_CCZ:
140+
qasm3 << "gate ccz _gate_q_0, _gate_q_1, _gate_q_2 {" << std::endl;
141+
qasm3 << " h _gate_q_2;" << std::endl;
142+
qasm3 << " ccx _gate_q_0, _gate_q_1, _gate_q_2;" << std::endl;
143+
qasm3 << " h _gate_q_2;" << std::endl;
144+
qasm3 << "}" << std::endl;
145+
break;
146+
case QkGate_RXX:
147+
qasm3 << "gate rxx(p0) _gate_q_0, _gate_q_1 {" << std::endl;
148+
qasm3 << " h _gate_q_0;" << std::endl;
149+
qasm3 << " h _gate_q_1;" << std::endl;
150+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
151+
qasm3 << " rz(p0) _gate_q_1;" << std::endl;
152+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
153+
qasm3 << " h _gate_q_1;" << std::endl;
154+
qasm3 << " h _gate_q_0;" << std::endl;
155+
qasm3 << "}" << std::endl;
156+
break;
157+
case QkGate_RZX:
158+
qasm3 << "gate rzx(p0) _gate_q_0, _gate_q_1 {" << std::endl;
159+
qasm3 << " h _gate_q_1;" << std::endl;
160+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
161+
qasm3 << " rz(p0) _gate_q_1;" << std::endl;
162+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
163+
qasm3 << " h _gate_q_1;" << std::endl;
164+
qasm3 << "}" << std::endl;
165+
break;
166+
case QkGate_RZZ:
167+
qasm3 << "gate rzz(p0) _gate_q_0, _gate_q_1 {" << std::endl;
168+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
169+
qasm3 << " rz(p0) _gate_q_1;" << std::endl;
170+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
171+
qasm3 << "}" << std::endl;
172+
break;
173+
case QkGate_RCCX:
174+
qasm3 << "gate rccx _gate_q_0, _gate_q_1, _gate_q_2 {" << std::endl;
175+
qasm3 << " h _gate_q_2;" << std::endl;
176+
qasm3 << " t _gate_q_2;" << std::endl;
177+
qasm3 << " cx _gate_q_1, _gate_q_2;" << std::endl;
178+
qasm3 << " tdg _gate_q_2;" << std::endl;
179+
qasm3 << " cx _gate_q_0, _gate_q_2;" << std::endl;
180+
qasm3 << " t _gate_q_2;" << std::endl;
181+
qasm3 << " cx _gate_q_1, _gate_q_2;" << std::endl;
182+
qasm3 << " tdg _gate_q_2;" << std::endl;
183+
qasm3 << " h _gate_q_2;" << std::endl;
184+
qasm3 << "}" << std::endl;
185+
break;
186+
case QkGate_C3X:
187+
qasm3 << "gate mcx _gate_q_0, _gate_q_1, _gate_q_2, _gate_q_3 {"
188+
<< std::endl;
189+
qasm3 << " h _gate_q_3;" << std::endl;
190+
qasm3 << " p(pi/8) _gate_q_0;" << std::endl;
191+
qasm3 << " p(pi/8) _gate_q_1;" << std::endl;
192+
qasm3 << " p(pi/8) _gate_q_2;" << std::endl;
193+
qasm3 << " p(pi/8) _gate_q_3;" << std::endl;
194+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
195+
qasm3 << " p(-pi/8) _gate_q_1;" << std::endl;
196+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
197+
qasm3 << " cx _gate_q_1, _gate_q_2;" << std::endl;
198+
qasm3 << " p(-pi/8) _gate_q_2;" << std::endl;
199+
qasm3 << " cx _gate_q_0, _gate_q_2;" << std::endl;
200+
qasm3 << " p(pi/8) _gate_q_2;" << std::endl;
201+
qasm3 << " cx _gate_q_1, _gate_q_2;" << std::endl;
202+
qasm3 << " p(-pi/8) _gate_q_2;" << std::endl;
203+
qasm3 << " cx _gate_q_0, _gate_q_2;" << std::endl;
204+
qasm3 << " cx _gate_q_2, _gate_q_3;" << std::endl;
205+
qasm3 << " p(-pi/8) _gate_q_3;" << std::endl;
206+
qasm3 << " cx _gate_q_1, _gate_q_3;" << std::endl;
207+
qasm3 << " p(pi/8) _gate_q_3;" << std::endl;
208+
qasm3 << " cx _gate_q_2, _gate_q_3;" << std::endl;
209+
qasm3 << " p(-pi/8) _gate_q_3;" << std::endl;
210+
qasm3 << " cx _gate_q_0, _gate_q_3;" << std::endl;
211+
qasm3 << " p(pi/8) _gate_q_3;" << std::endl;
212+
qasm3 << " cx _gate_q_2, _gate_q_3;" << std::endl;
213+
qasm3 << " p(-pi/8) _gate_q_3;" << std::endl;
214+
qasm3 << " cx _gate_q_1, _gate_q_3;" << std::endl;
215+
qasm3 << " p(pi/8) _gate_q_3;" << std::endl;
216+
qasm3 << " cx _gate_q_2, _gate_q_3;" << std::endl;
217+
qasm3 << " p(-pi/8) _gate_q_3;" << std::endl;
218+
qasm3 << " cx _gate_q_0, _gate_q_3;" << std::endl;
219+
qasm3 << " h _gate_q_3;" << std::endl;
220+
qasm3 << "}" << std::endl;
221+
break;
222+
case QkGate_C3SX:
223+
qasm3 << "gate c3sx _gate_q_0, _gate_q_1, _gate_q_2, _gate_q_3 {"
224+
<< std::endl;
225+
qasm3 << " h _gate_q_3;" << std::endl;
226+
qasm3 << " cp(pi/8) _gate_q_0, _gate_q_3;" << std::endl;
227+
qasm3 << " h _gate_q_3;" << std::endl;
228+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
229+
qasm3 << " h _gate_q_3;" << std::endl;
230+
qasm3 << " cp(-pi/8) _gate_q_1, _gate_q_3;" << std::endl;
231+
qasm3 << " h _gate_q_3;" << std::endl;
232+
qasm3 << " cx _gate_q_0, _gate_q_1;" << std::endl;
233+
qasm3 << " h _gate_q_3;" << std::endl;
234+
qasm3 << " cp(pi/8) _gate_q_1, _gate_q_3;" << std::endl;
235+
qasm3 << " h _gate_q_3;" << std::endl;
236+
qasm3 << " cx _gate_q_1, _gate_q_2;" << std::endl;
237+
qasm3 << " h _gate_q_3;" << std::endl;
238+
qasm3 << " cp(-pi/8) _gate_q_2, _gate_q_3;" << std::endl;
239+
qasm3 << " h _gate_q_3;" << std::endl;
240+
qasm3 << " cx _gate_q_0, _gate_q_2;" << std::endl;
241+
qasm3 << " h _gate_q_3;" << std::endl;
242+
qasm3 << " cp(pi/8) _gate_q_2, _gate_q_3;" << std::endl;
243+
qasm3 << " h _gate_q_3;" << std::endl;
244+
qasm3 << " cx _gate_q_1, _gate_q_2;" << std::endl;
245+
qasm3 << " h _gate_q_3;" << std::endl;
246+
qasm3 << " cp(-pi/8) _gate_q_2, _gate_q_3;" << std::endl;
247+
qasm3 << " h _gate_q_3;" << std::endl;
248+
qasm3 << " cx _gate_q_0, _gate_q_2;" << std::endl;
249+
qasm3 << " h _gate_q_3;" << std::endl;
250+
qasm3 << " cp(pi/8) _gate_q_2, _gate_q_3;" << std::endl;
251+
qasm3 << " h _gate_q_3;" << std::endl;
252+
qasm3 << "}" << std::endl;
253+
break;
254+
case QkGate_RC3X:
255+
qasm3 << "gate rcccx _gate_q_0, _gate_q_1, _gate_q_2, _gate_q_3 {"
256+
<< std::endl;
257+
qasm3 << " h _gate_q_3;" << std::endl;
258+
qasm3 << " t _gate_q_3;" << std::endl;
259+
qasm3 << " cx _gate_q_2, _gate_q_3;" << std::endl;
260+
qasm3 << " tdg _gate_q_3;" << std::endl;
261+
qasm3 << " h _gate_q_3;" << std::endl;
262+
qasm3 << " cx _gate_q_0, _gate_q_3;" << std::endl;
263+
qasm3 << " t _gate_q_3;" << std::endl;
264+
qasm3 << " cx _gate_q_1, _gate_q_3;" << std::endl;
265+
qasm3 << " tdg _gate_q_3;" << std::endl;
266+
qasm3 << " cx _gate_q_0, _gate_q_3;" << std::endl;
267+
qasm3 << " t _gate_q_3;" << std::endl;
268+
qasm3 << " cx _gate_q_1, _gate_q_3;" << std::endl;
269+
qasm3 << " tdg _gate_q_3;" << std::endl;
270+
qasm3 << " h _gate_q_3;" << std::endl;
271+
qasm3 << " t _gate_q_3;" << std::endl;
272+
qasm3 << " cx _gate_q_2, _gate_q_3;" << std::endl;
273+
qasm3 << " tdg _gate_q_3;" << std::endl;
274+
qasm3 << " h _gate_q_3;" << std::endl;
275+
qasm3 << "}" << std::endl;
276+
break;
277+
case QkGate_CU1:
278+
qasm3 << "gate cu1(p0) _gate_q_0, _gate_q_1 {" << std::endl;
279+
qasm3 << " cp(p0) _gate_q_0 _gate_q_1;" << std::endl;
280+
qasm3 << "}" << std::endl;
281+
break;
282+
case QkGate_CU3:
283+
qasm3 << "gate cu3(p0, p1, p2) _gate_q_0, _gate_q_1 {" << std::endl;
284+
qasm3 << " cu(p0, p1, p2, 0) _gate_q_0 _gate_q_1;" << std::endl;
285+
qasm3 << "}" << std::endl;
286+
break;
287+
default:
288+
break;
289+
}
290+
}
291+
}
292+
qk_opcounts_clear(&opcounts);
293+
294+
// save ops
295+
uint_t nops;
296+
nops = qk_circuit_num_instructions(rust_circuit_.get());
297+
298+
// Declare registers
299+
// After transpilation, qubit registers will be mapped to physical registers,
300+
// so we need to combined them in a single quantum register "q";
301+
const std::string qreg_name = "q";
302+
qasm3 << "qubit[" << num_qubits() << "] " << qreg_name << ";" << std::endl;
303+
for (const auto &creg : cregs_) {
304+
qasm3 << "bit[" << creg.size() << "] " << creg.name() << ";" << std::endl;
305+
}
306+
307+
auto recover_reg_data =
308+
[this](uint_t index) -> std::pair<std::string, uint_t> {
309+
auto it = std::upper_bound(cregs_.begin(), cregs_.end(), index,
310+
[](uint_t v, const ClassicalRegister &reg) {
311+
return v < reg.base_index();
312+
});
313+
assert(it != cregs_.begin());
314+
it = std::prev(it);
315+
return std::make_pair(it->name(), index - it->base_index());
316+
};
317+
318+
for (uint_t i = 0; i < nops; i++) {
319+
QkCircuitInstruction *op = new QkCircuitInstruction;
320+
qk_circuit_get_instruction(rust_circuit_.get(), i, op);
321+
if (op->num_clbits > 0) {
322+
if (op->num_qubits == op->num_clbits) {
323+
for (uint_t j = 0; j < op->num_qubits; j++) {
324+
const auto creg_data = recover_reg_data(op->clbits[j]);
325+
qasm3 << creg_data.first << "[" << creg_data.second
326+
<< "] = " << op->name << " " << qreg_name << "["
327+
<< op->qubits[j] << "];" << std::endl;
328+
}
329+
}
330+
} else {
331+
if (strcmp(op->name, "u") == 0) {
332+
qasm3 << "U";
333+
} else {
334+
qasm3 << op->name;
335+
}
336+
if (op->num_params > 0) {
337+
qasm3 << "(";
338+
for (uint_t j = 0; j < op->num_params; j++) {
339+
char *param = qk_param_str(op->params[j]);
340+
qasm3 << param;
341+
qk_str_free(param);
342+
if (j != op->num_params - 1)
343+
qasm3 << ", ";
344+
}
345+
qasm3 << ")";
346+
}
347+
if (op->num_qubits > 0) {
348+
qasm3 << " ";
349+
for (uint_t j = 0; j < op->num_qubits; j++) {
350+
qasm3 << qreg_name << "[" << op->qubits[j] << "]";
351+
if (j != op->num_qubits - 1)
352+
qasm3 << ", ";
353+
}
354+
}
355+
qasm3 << ";" << std::endl;
356+
}
357+
qk_circuit_instruction_clear(op);
358+
}
359+
360+
return qasm3.str();
361+
}

0 commit comments

Comments
 (0)