Skip to content

Commit 9463f52

Browse files
authored
Merge pull request #215 from BQSKit/controlled-qasm
QASM support for singly-controlled ControlledGates.
2 parents 1ee59f1 + 5463f9f commit 9463f52

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

bqskit/ir/gates/composed/controlled.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,33 @@ def __init__(
286286
ctrl_U = np.kron(self.ctrl, U) + self.ihalf
287287
self._utry = UnitaryMatrix(ctrl_U, self.radixes)
288288

289+
@property
290+
def qasm_name(self) -> str:
291+
"""
292+
Override default `Gate.qasm_name` method.
293+
294+
If the core gate is a standard gate, this function will output
295+
qasm in the form 'c+<gate_qasm>'. Otherwise an error will be raised.
296+
297+
Raises:
298+
ValueError: If the core gate is non-standard in OpenQASM 2.0.
299+
"""
300+
_core_gate = self.gate.qasm_name
301+
if self.num_controls <= 2:
302+
_controls = 'c' * self.num_controls
303+
else:
304+
_controls = f'c{self.num_controls}'
305+
qasm_name = _controls + _core_gate
306+
supported_gates = ('cu1', 'cu2', 'cu3', 'cswap', 'c3x', 'c4x')
307+
if qasm_name not in supported_gates:
308+
raise ValueError(
309+
f'Controlled gate {_core_gate} with {self.num_controls} '
310+
'controls is not a standard OpenQASM 2.0 identifier. '
311+
'To encode this gate, try decomposing it into gates with'
312+
'standard identifiers.',
313+
)
314+
return qasm_name
315+
289316
def get_unitary(self, params: RealVector = []) -> UnitaryMatrix:
290317
"""Return the unitary for this gate, see :class:`Unitary` for more."""
291318
if hasattr(self, '_utry'):

tests/ir/lang/test_controlled_qasm.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from __future__ import annotations
2+
3+
from bqskit.ir.lang.qasm2 import OPENQASM2Language
4+
5+
6+
class TestControlledQASM:
7+
def test_cu1(self) -> None:
8+
9+
input_qasm = (
10+
'OPENQASM 2.0;\n'
11+
'include "qelib1.inc";\n'
12+
'qreg q[2];\n'
13+
'cu1(3.1415) q[0], q[1];\n'
14+
)
15+
circuit = OPENQASM2Language().decode(input_qasm)
16+
17+
output_qasm = circuit.to('qasm')
18+
19+
assert input_qasm == output_qasm
20+
21+
def test_cu2(self) -> None:
22+
23+
input_qasm = (
24+
'OPENQASM 2.0;\n'
25+
'include "qelib1.inc";\n'
26+
'qreg q[2];\n'
27+
'cu2(3.1415, 0.0) q[0], q[1];\n'
28+
)
29+
circuit = OPENQASM2Language().decode(input_qasm)
30+
31+
output_qasm = circuit.to('qasm')
32+
33+
assert input_qasm == output_qasm
34+
35+
def test_cu3(self) -> None:
36+
37+
input_qasm = (
38+
'OPENQASM 2.0;\n'
39+
'include "qelib1.inc";\n'
40+
'qreg q[2];\n'
41+
'cu3(3.1415, 0.0, -4.0) q[0], q[1];\n'
42+
)
43+
circuit = OPENQASM2Language().decode(input_qasm)
44+
45+
output_qasm = circuit.to('qasm')
46+
47+
assert input_qasm == output_qasm
48+
49+
def test_cswap(self) -> None:
50+
51+
input_qasm = (
52+
'OPENQASM 2.0;\n'
53+
'include "qelib1.inc";\n'
54+
'qreg q[3];\n'
55+
'cswap q[0], q[1], q[2];\n'
56+
)
57+
circuit = OPENQASM2Language().decode(input_qasm)
58+
59+
output_qasm = circuit.to('qasm')
60+
61+
assert input_qasm == output_qasm
62+
63+
def test_c3x(self) -> None:
64+
65+
input_qasm = (
66+
'OPENQASM 2.0;\n'
67+
'include "qelib1.inc";\n'
68+
'qreg q[4];\n'
69+
'c3x q[0], q[1], q[2], q[3];\n'
70+
)
71+
circuit = OPENQASM2Language().decode(input_qasm)
72+
73+
output_qasm = circuit.to('qasm')
74+
75+
assert input_qasm == output_qasm
76+
77+
def test_c4x(self) -> None:
78+
79+
input_qasm = (
80+
'OPENQASM 2.0;\n'
81+
'include "qelib1.inc";\n'
82+
'qreg q[5];\n'
83+
'c4x q[0], q[1], q[2], q[3], q[4];\n'
84+
)
85+
circuit = OPENQASM2Language().decode(input_qasm)
86+
87+
output_qasm = circuit.to('qasm')
88+
89+
assert input_qasm == output_qasm
90+
91+
def test_ch(self) -> None:
92+
93+
input_qasm = (
94+
'OPENQASM 2.0;\n'
95+
'include "qelib1.inc";\n'
96+
'qreg q[2];\n'
97+
'ch q[0], q[1];\n'
98+
)
99+
try:
100+
OPENQASM2Language().decode(input_qasm)
101+
except ValueError:
102+
assert True

0 commit comments

Comments
 (0)