Skip to content

Commit

Permalink
Support custom gate defintions in QASM parser (#6917)
Browse files Browse the repository at this point in the history
Resolves #3560

* Tests verify parsed vs expected, for unparameterized, parameterized,
and for broadcasted qregs.
* They also use `assert_qiskit_parsed_qasm_consistent_with_unitary` to
ensure consistency of parsed circuit (and sanity check that the provided
QASM definition is actually valid).
* Several tests for invalid gate definitions or invocations and verify
similar error message for Cirq and qiskit parsers.
* One odd instance where qiskit does not throw an error on an invalid
QASM circuit, even though simulating it in qiskit fails; chalking it up
to a qiskit bug.
  • Loading branch information
daxfohl authored Jan 17, 2025
1 parent 5cc14ba commit 2b49589
Show file tree
Hide file tree
Showing 5 changed files with 558 additions and 80 deletions.
4 changes: 2 additions & 2 deletions cirq-core/cirq/circuits/qasm_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,10 @@ def on_stuck(bad_op):
if should_annotate:
output_line_gap(1)
if isinstance(main_op, ops.GateOperation):
x = str(main_op.gate).replace('\n', '\n //')
x = str(main_op.gate).replace('\n', '\n// ')
output(f'// Gate: {x!s}\n')
else:
x = str(main_op).replace('\n', '\n //')
x = str(main_op).replace('\n', '\n// ')
output(f'// Operation: {x!s}\n')

for qasm in qasms:
Expand Down
5 changes: 5 additions & 0 deletions cirq-core/cirq/contrib/qasm_import/_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self):
'creg': 'CREG',
'measure': 'MEASURE',
'reset': 'RESET',
'gate': 'GATE',
'if': 'IF',
'->': 'ARROW',
'==': 'EQ',
Expand Down Expand Up @@ -120,6 +121,10 @@ def t_RESET(self, t):
r"""reset"""
return t

def t_GATE(self, t):
r"""gate"""
return t

def t_IF(self, t):
r"""if"""
return t
Expand Down
68 changes: 68 additions & 0 deletions cirq-core/cirq/contrib/qasm_import/_lexer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,74 @@ def test_creg():
assert token.value == ";"


def test_custom_gate():
lexer = QasmLexer()
lexer.input('gate name(param1,param2) q1, q2 {X(q1)}')
token = lexer.token()
assert token.type == "GATE"
assert token.value == "gate"

token = lexer.token()
assert token.type == "ID"
assert token.value == "name"

token = lexer.token()
assert token.type == "("
assert token.value == "("

token = lexer.token()
assert token.type == "ID"
assert token.value == "param1"

token = lexer.token()
assert token.type == ","
assert token.value == ","

token = lexer.token()
assert token.type == "ID"
assert token.value == "param2"

token = lexer.token()
assert token.type == ")"
assert token.value == ")"

token = lexer.token()
assert token.type == "ID"
assert token.value == "q1"

token = lexer.token()
assert token.type == ","
assert token.value == ","

token = lexer.token()
assert token.type == "ID"
assert token.value == "q2"

token = lexer.token()
assert token.type == "{"
assert token.value == "{"

token = lexer.token()
assert token.type == "ID"
assert token.value == "X"

token = lexer.token()
assert token.type == "("
assert token.value == "("

token = lexer.token()
assert token.type == "ID"
assert token.value == "q1"

token = lexer.token()
assert token.type == ")"
assert token.value == ")"

token = lexer.token()
assert token.type == "}"
assert token.value == "}"


def test_error():
lexer = QasmLexer()
lexer.input('θ')
Expand Down
Loading

0 comments on commit 2b49589

Please sign in to comment.