Skip to content

Commit 39f12f1

Browse files
committed
Apply review comments: clarify docstrings, add test for control flow instructions
1 parent 0c765ea commit 39f12f1

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

qiskit/qasm3/exporter.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,14 @@ def _build_quantum_call_parameters(self, parameters) -> list[ast.Expression]:
13131313

13141314
def build_defcal_call(self, instruction: CircuitInstruction, defcal: DefcalInstruction):
13151315
"""Build a statement associated with a defcal instruction."""
1316-
# We forbade return types other than `Bool` and `None` in the initialiser.
1316+
# We forbade return types other than `Bool` and `None` in the initialiser,
1317+
# but we error so that this breaks if we support the full defcal spec later on.
1318+
allowed_defcal_types = (None, types.Bool())
1319+
if defcal.return_type not in allowed_defcal_types:
1320+
raise QASM3ExporterError(
1321+
f"The defcal '{defcal.name}' associated with instructions with name '{instruction.name}'"
1322+
f" returns an unsupported classical type: {defcal.return_type}"
1323+
)
13171324
returns_bit = defcal.return_type is not None
13181325
# Check simple consistency.
13191326
if (
@@ -1341,7 +1348,8 @@ def build_gate_call(self, instruction: CircuitInstruction):
13411348
This will also push the gate into the symbol table (if required), including recursively
13421349
defining the gate blocks.
13431350
1344-
If ``ident`` is given, symbol-resolution will be skipped."""
1351+
If the operation identifier is found in the symbol table, symbol-resolution will be skipped.
1352+
"""
13451353
operation = instruction.operation
13461354
if hasattr(operation, "_qasm_decomposition"):
13471355
operation = operation._qasm_decomposition()

test/python/qasm3/test_export.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2411,6 +2411,36 @@ def test_defcal_overriding_instruction_name(self):
24112411
qubit[1] q;
24122412
h q[0];
24132413
c[0] = measure_2 q[0];
2414+
"""
2415+
self.assertEqual(expected.strip(), out_qasm.strip())
2416+
2417+
def test_defcal_overriding_ctrl_flow_op_name(self):
2418+
"""Test overriding ContinueLoopOp and BreakLoopOp instruction names using defcals."""
2419+
# These are edge-case control flow ops that don't subclass ControlFlowOp and
2420+
# therefore can be overwritten using defcals like regular instructions.
2421+
qc = QuantumCircuit(1, 1)
2422+
qc.h(0)
2423+
qc.break_loop()
2424+
qc.continue_loop()
2425+
2426+
defcals = {
2427+
"break_loop": DefcalInstruction("my_name_break", 0, 1, types.Bool()),
2428+
"continue_loop": DefcalInstruction("my_name_continue", 0, 1, types.Bool()),
2429+
}
2430+
out_qasm = dumps(
2431+
qc,
2432+
includes=(),
2433+
basis_gates=("h", "cx"),
2434+
disable_constants=True,
2435+
implicit_defcals=defcals,
2436+
)
2437+
expected = """
2438+
OPENQASM 3.0;
2439+
bit[1] c;
2440+
qubit[1] q;
2441+
h q[0];
2442+
c[0] = my_name_break q[0];
2443+
c[0] = my_name_continue q[0];
24142444
"""
24152445
self.assertEqual(expected.strip(), out_qasm.strip())
24162446

0 commit comments

Comments
 (0)