Skip to content

Commit ce846b8

Browse files
authored
Unroll broadcasted operations when producing QASM from SLR (#96)
* unroll broadcast operations * add comment * add error message * Fixing regression tests * linting ---------
1 parent b34024b commit ce846b8

File tree

92 files changed

+3474
-497
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+3474
-497
lines changed

python/quantum-pecos/src/pecos/slr/gen_codes/gen_qasm.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from __future__ import annotations
1313

1414
from pecos import __version__
15+
from pecos.slr.vars import QReg
1516

1617

1718
class QASMGenerator:
@@ -294,14 +295,25 @@ def qgate_qasm(self, op, repr_str: str | None = None):
294295
op.qargs = (op.qargs,)
295296

296297
for q in op.qargs:
297-
if isinstance(q, tuple):
298+
if isinstance(q, QReg):
299+
# Broadcasting across a qubit register is inconsistent with the current Permute
300+
# strategy, so "unroll" broadcast operations to make them act on individual qubits.
301+
# See, for example, https://github.com/PECOS-packages/PECOS/issues/95.
302+
if op.qsize != 1:
303+
msg = "Only single-qubit gates can be broadcast across a qubit register"
304+
raise Exception(msg)
305+
lines = [f"{repr_str} {qubit};" for qubit in q]
306+
str_list.extend(lines)
307+
308+
elif isinstance(q, tuple):
298309
if len(q) != op.qsize:
299310
msg = f"Expected size {op.qsize} got size {len(q)}"
300311
raise Exception(msg)
301312
qs = ",".join([str(qi) for qi in q])
302313
str_list.append(f"{repr_str} {qs};")
303314

304-
str_list.append(f"{repr_str} {str(q)};")
315+
else:
316+
str_list.append(f"{repr_str} {q};")
305317

306318
return "\n".join(str_list)
307319

python/tests/pecos/regression/test_qasm/regression_qasm/local_steane_code_program.t_gate_+X_X.qasm

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ creg saux_verify_prep[32];
3636

3737
barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
3838

39-
reset sin_d;
39+
reset sin_d[0];
40+
reset sin_d[1];
41+
reset sin_d[2];
42+
reset sin_d[3];
43+
reset sin_d[4];
44+
reset sin_d[5];
45+
reset sin_d[6];
4046
reset sin_a[0];
4147
barrier sin_d, sin_a[0];
4248
h sin_d[0];
@@ -62,7 +68,13 @@ measure sin_a[0] -> sin_verify_prep[0];
6268

6369
if(sin_verify_prep[0] == 1) barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
6470

65-
if(sin_verify_prep[0] == 1) reset sin_d;
71+
if(sin_verify_prep[0] == 1) reset sin_d[0];
72+
if(sin_verify_prep[0] == 1) reset sin_d[1];
73+
if(sin_verify_prep[0] == 1) reset sin_d[2];
74+
if(sin_verify_prep[0] == 1) reset sin_d[3];
75+
if(sin_verify_prep[0] == 1) reset sin_d[4];
76+
if(sin_verify_prep[0] == 1) reset sin_d[5];
77+
if(sin_verify_prep[0] == 1) reset sin_d[6];
6678
if(sin_verify_prep[0] == 1) reset sin_a[0];
6779
if(sin_verify_prep[0] == 1) barrier sin_d, sin_a[0];
6880
if(sin_verify_prep[0] == 1) h sin_d[0];
@@ -88,7 +100,13 @@ if(sin_verify_prep[0] == 1) measure sin_a[0] -> sin_verify_prep[0];
88100

89101
if(sin_verify_prep[0] == 1) barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
90102

91-
if(sin_verify_prep[0] == 1) reset sin_d;
103+
if(sin_verify_prep[0] == 1) reset sin_d[0];
104+
if(sin_verify_prep[0] == 1) reset sin_d[1];
105+
if(sin_verify_prep[0] == 1) reset sin_d[2];
106+
if(sin_verify_prep[0] == 1) reset sin_d[3];
107+
if(sin_verify_prep[0] == 1) reset sin_d[4];
108+
if(sin_verify_prep[0] == 1) reset sin_d[5];
109+
if(sin_verify_prep[0] == 1) reset sin_d[6];
92110
if(sin_verify_prep[0] == 1) reset sin_a[0];
93111
if(sin_verify_prep[0] == 1) barrier sin_d, sin_a[0];
94112
if(sin_verify_prep[0] == 1) h sin_d[0];
@@ -112,7 +130,13 @@ if(sin_verify_prep[0] == 1) cx sin_d[3], sin_a[0];
112130
if(sin_verify_prep[0] == 1) measure sin_a[0] -> sin_verify_prep[0];
113131

114132
// Logical H
115-
h sin_d;
133+
h sin_d[0];
134+
h sin_d[1];
135+
h sin_d[2];
136+
h sin_d[3];
137+
h sin_d[4];
138+
h sin_d[5];
139+
h sin_d[6];
116140
saux_scratch = 0;
117141
reset saux_d[6];
118142
ry(0.7853981633974483) saux_d[6];
@@ -371,10 +395,22 @@ if(saux_syn_meas == 6) saux_c[2] = saux_c[2] ^ 1;
371395
saux_c[2] = saux_c[2] ^ saux_c[3];
372396
sin_c[5] = saux_c[2];
373397
// Logical SZ
374-
if(sin_c[5] == 1) rz(-pi/2) sin_d;
398+
if(sin_c[5] == 1) rz(-pi/2) sin_d[0];
399+
if(sin_c[5] == 1) rz(-pi/2) sin_d[1];
400+
if(sin_c[5] == 1) rz(-pi/2) sin_d[2];
401+
if(sin_c[5] == 1) rz(-pi/2) sin_d[3];
402+
if(sin_c[5] == 1) rz(-pi/2) sin_d[4];
403+
if(sin_c[5] == 1) rz(-pi/2) sin_d[5];
404+
if(sin_c[5] == 1) rz(-pi/2) sin_d[6];
375405
// Destructive logical X measurement
376406
// Logical SYdg
377-
ry(-pi/2) sin_d;
407+
ry(-pi/2) sin_d[0];
408+
ry(-pi/2) sin_d[1];
409+
ry(-pi/2) sin_d[2];
410+
ry(-pi/2) sin_d[3];
411+
ry(-pi/2) sin_d[4];
412+
ry(-pi/2) sin_d[5];
413+
ry(-pi/2) sin_d[6];
378414

379415
barrier sin_d;
380416

@@ -824,7 +860,13 @@ m_reject[1] = saux_scratch[2];
824860

825861
barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
826862

827-
reset sin_d;
863+
reset sin_d[0];
864+
reset sin_d[1];
865+
reset sin_d[2];
866+
reset sin_d[3];
867+
reset sin_d[4];
868+
reset sin_d[5];
869+
reset sin_d[6];
828870
reset sin_a[0];
829871
barrier sin_d, sin_a[0];
830872
h sin_d[0];
@@ -850,7 +892,13 @@ measure sin_a[0] -> sin_verify_prep[0];
850892

851893
if(sin_verify_prep[0] == 1) barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
852894

853-
if(sin_verify_prep[0] == 1) reset sin_d;
895+
if(sin_verify_prep[0] == 1) reset sin_d[0];
896+
if(sin_verify_prep[0] == 1) reset sin_d[1];
897+
if(sin_verify_prep[0] == 1) reset sin_d[2];
898+
if(sin_verify_prep[0] == 1) reset sin_d[3];
899+
if(sin_verify_prep[0] == 1) reset sin_d[4];
900+
if(sin_verify_prep[0] == 1) reset sin_d[5];
901+
if(sin_verify_prep[0] == 1) reset sin_d[6];
854902
if(sin_verify_prep[0] == 1) reset sin_a[0];
855903
if(sin_verify_prep[0] == 1) barrier sin_d, sin_a[0];
856904
if(sin_verify_prep[0] == 1) h sin_d[0];
@@ -874,7 +922,13 @@ if(sin_verify_prep[0] == 1) cx sin_d[3], sin_a[0];
874922
if(sin_verify_prep[0] == 1) measure sin_a[0] -> sin_verify_prep[0];
875923

876924
// Logical H
877-
h sin_d;
925+
h sin_d[0];
926+
h sin_d[1];
927+
h sin_d[2];
928+
h sin_d[3];
929+
h sin_d[4];
930+
h sin_d[5];
931+
h sin_d[6];
878932
// Transversal Logical CX
879933
barrier sin_d, saux_d;
880934
cx sin_d[0], saux_d[0];
@@ -927,10 +981,22 @@ if(saux_syn_meas == 6) saux_c[2] = saux_c[2] ^ 1;
927981
saux_c[2] = saux_c[2] ^ saux_c[3];
928982
m_t[0] = saux_c[2];
929983
// Logical SZ
930-
if(sin_c[5] == 1) rz(-pi/2) sin_d;
984+
if(sin_c[5] == 1) rz(-pi/2) sin_d[0];
985+
if(sin_c[5] == 1) rz(-pi/2) sin_d[1];
986+
if(sin_c[5] == 1) rz(-pi/2) sin_d[2];
987+
if(sin_c[5] == 1) rz(-pi/2) sin_d[3];
988+
if(sin_c[5] == 1) rz(-pi/2) sin_d[4];
989+
if(sin_c[5] == 1) rz(-pi/2) sin_d[5];
990+
if(sin_c[5] == 1) rz(-pi/2) sin_d[6];
931991
// Destructive logical X measurement
932992
// Logical SYdg
933-
ry(-pi/2) sin_d;
993+
ry(-pi/2) sin_d[0];
994+
ry(-pi/2) sin_d[1];
995+
ry(-pi/2) sin_d[2];
996+
ry(-pi/2) sin_d[3];
997+
ry(-pi/2) sin_d[4];
998+
ry(-pi/2) sin_d[5];
999+
ry(-pi/2) sin_d[6];
9341000

9351001
barrier sin_d;
9361002

python/tests/pecos/regression/test_qasm/regression_qasm/local_steane_code_program.t_gate_+X_Y.qasm

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ creg saux_verify_prep[32];
3636

3737
barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
3838

39-
reset sin_d;
39+
reset sin_d[0];
40+
reset sin_d[1];
41+
reset sin_d[2];
42+
reset sin_d[3];
43+
reset sin_d[4];
44+
reset sin_d[5];
45+
reset sin_d[6];
4046
reset sin_a[0];
4147
barrier sin_d, sin_a[0];
4248
h sin_d[0];
@@ -62,7 +68,13 @@ measure sin_a[0] -> sin_verify_prep[0];
6268

6369
if(sin_verify_prep[0] == 1) barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
6470

65-
if(sin_verify_prep[0] == 1) reset sin_d;
71+
if(sin_verify_prep[0] == 1) reset sin_d[0];
72+
if(sin_verify_prep[0] == 1) reset sin_d[1];
73+
if(sin_verify_prep[0] == 1) reset sin_d[2];
74+
if(sin_verify_prep[0] == 1) reset sin_d[3];
75+
if(sin_verify_prep[0] == 1) reset sin_d[4];
76+
if(sin_verify_prep[0] == 1) reset sin_d[5];
77+
if(sin_verify_prep[0] == 1) reset sin_d[6];
6678
if(sin_verify_prep[0] == 1) reset sin_a[0];
6779
if(sin_verify_prep[0] == 1) barrier sin_d, sin_a[0];
6880
if(sin_verify_prep[0] == 1) h sin_d[0];
@@ -88,7 +100,13 @@ if(sin_verify_prep[0] == 1) measure sin_a[0] -> sin_verify_prep[0];
88100

89101
if(sin_verify_prep[0] == 1) barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
90102

91-
if(sin_verify_prep[0] == 1) reset sin_d;
103+
if(sin_verify_prep[0] == 1) reset sin_d[0];
104+
if(sin_verify_prep[0] == 1) reset sin_d[1];
105+
if(sin_verify_prep[0] == 1) reset sin_d[2];
106+
if(sin_verify_prep[0] == 1) reset sin_d[3];
107+
if(sin_verify_prep[0] == 1) reset sin_d[4];
108+
if(sin_verify_prep[0] == 1) reset sin_d[5];
109+
if(sin_verify_prep[0] == 1) reset sin_d[6];
92110
if(sin_verify_prep[0] == 1) reset sin_a[0];
93111
if(sin_verify_prep[0] == 1) barrier sin_d, sin_a[0];
94112
if(sin_verify_prep[0] == 1) h sin_d[0];
@@ -112,7 +130,13 @@ if(sin_verify_prep[0] == 1) cx sin_d[3], sin_a[0];
112130
if(sin_verify_prep[0] == 1) measure sin_a[0] -> sin_verify_prep[0];
113131

114132
// Logical H
115-
h sin_d;
133+
h sin_d[0];
134+
h sin_d[1];
135+
h sin_d[2];
136+
h sin_d[3];
137+
h sin_d[4];
138+
h sin_d[5];
139+
h sin_d[6];
116140
saux_scratch = 0;
117141
reset saux_d[6];
118142
ry(0.7853981633974483) saux_d[6];
@@ -371,10 +395,22 @@ if(saux_syn_meas == 6) saux_c[2] = saux_c[2] ^ 1;
371395
saux_c[2] = saux_c[2] ^ saux_c[3];
372396
sin_c[5] = saux_c[2];
373397
// Logical SZ
374-
if(sin_c[5] == 1) rz(-pi/2) sin_d;
398+
if(sin_c[5] == 1) rz(-pi/2) sin_d[0];
399+
if(sin_c[5] == 1) rz(-pi/2) sin_d[1];
400+
if(sin_c[5] == 1) rz(-pi/2) sin_d[2];
401+
if(sin_c[5] == 1) rz(-pi/2) sin_d[3];
402+
if(sin_c[5] == 1) rz(-pi/2) sin_d[4];
403+
if(sin_c[5] == 1) rz(-pi/2) sin_d[5];
404+
if(sin_c[5] == 1) rz(-pi/2) sin_d[6];
375405
// Destructive logical Y measurement
376406
// Logical SX
377-
rx(-pi/2) sin_d;
407+
rx(-pi/2) sin_d[0];
408+
rx(-pi/2) sin_d[1];
409+
rx(-pi/2) sin_d[2];
410+
rx(-pi/2) sin_d[3];
411+
rx(-pi/2) sin_d[4];
412+
rx(-pi/2) sin_d[5];
413+
rx(-pi/2) sin_d[6];
378414

379415
barrier sin_d;
380416

@@ -826,7 +862,13 @@ m_reject[1] = saux_scratch[2];
826862

827863
barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
828864

829-
reset sin_d;
865+
reset sin_d[0];
866+
reset sin_d[1];
867+
reset sin_d[2];
868+
reset sin_d[3];
869+
reset sin_d[4];
870+
reset sin_d[5];
871+
reset sin_d[6];
830872
reset sin_a[0];
831873
barrier sin_d, sin_a[0];
832874
h sin_d[0];
@@ -852,7 +894,13 @@ measure sin_a[0] -> sin_verify_prep[0];
852894

853895
if(sin_verify_prep[0] == 1) barrier sin_d[0], sin_d[1], sin_d[2], sin_d[3], sin_d[4], sin_d[5], sin_d[6], sin_a[0];
854896

855-
if(sin_verify_prep[0] == 1) reset sin_d;
897+
if(sin_verify_prep[0] == 1) reset sin_d[0];
898+
if(sin_verify_prep[0] == 1) reset sin_d[1];
899+
if(sin_verify_prep[0] == 1) reset sin_d[2];
900+
if(sin_verify_prep[0] == 1) reset sin_d[3];
901+
if(sin_verify_prep[0] == 1) reset sin_d[4];
902+
if(sin_verify_prep[0] == 1) reset sin_d[5];
903+
if(sin_verify_prep[0] == 1) reset sin_d[6];
856904
if(sin_verify_prep[0] == 1) reset sin_a[0];
857905
if(sin_verify_prep[0] == 1) barrier sin_d, sin_a[0];
858906
if(sin_verify_prep[0] == 1) h sin_d[0];
@@ -876,7 +924,13 @@ if(sin_verify_prep[0] == 1) cx sin_d[3], sin_a[0];
876924
if(sin_verify_prep[0] == 1) measure sin_a[0] -> sin_verify_prep[0];
877925

878926
// Logical H
879-
h sin_d;
927+
h sin_d[0];
928+
h sin_d[1];
929+
h sin_d[2];
930+
h sin_d[3];
931+
h sin_d[4];
932+
h sin_d[5];
933+
h sin_d[6];
880934
// Transversal Logical CX
881935
barrier sin_d, saux_d;
882936
cx sin_d[0], saux_d[0];
@@ -929,10 +983,22 @@ if(saux_syn_meas == 6) saux_c[2] = saux_c[2] ^ 1;
929983
saux_c[2] = saux_c[2] ^ saux_c[3];
930984
m_t[0] = saux_c[2];
931985
// Logical SZ
932-
if(sin_c[5] == 1) rz(-pi/2) sin_d;
986+
if(sin_c[5] == 1) rz(-pi/2) sin_d[0];
987+
if(sin_c[5] == 1) rz(-pi/2) sin_d[1];
988+
if(sin_c[5] == 1) rz(-pi/2) sin_d[2];
989+
if(sin_c[5] == 1) rz(-pi/2) sin_d[3];
990+
if(sin_c[5] == 1) rz(-pi/2) sin_d[4];
991+
if(sin_c[5] == 1) rz(-pi/2) sin_d[5];
992+
if(sin_c[5] == 1) rz(-pi/2) sin_d[6];
933993
// Destructive logical Y measurement
934994
// Logical SX
935-
rx(-pi/2) sin_d;
995+
rx(-pi/2) sin_d[0];
996+
rx(-pi/2) sin_d[1];
997+
rx(-pi/2) sin_d[2];
998+
rx(-pi/2) sin_d[3];
999+
rx(-pi/2) sin_d[4];
1000+
rx(-pi/2) sin_d[5];
1001+
rx(-pi/2) sin_d[6];
9361002

9371003
barrier sin_d;
9381004

0 commit comments

Comments
 (0)