Skip to content

Commit f62bfef

Browse files
committed
Fix operator precedence bug in exp_pauli qubit concatenation
In `PyKernel.exp_pauli()`, the `+` operator binds tighter than the ternary `if/else`, causing `qubitsList` to be silently dropped when `quantumVal` is not None. Add parentheses to ensure individual qubits are always concatenated with the register.
1 parent 7655540 commit f62bfef

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

python/cudaq/kernel/kernel_builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ def exp_pauli(self, theta, *args):
956956
if len(qubitsList) > 0:
957957
quantumVal = quake.ConcatOp(
958958
quake.VeqType.get(),
959-
[quantumVal] if quantumVal is not None else [] +
959+
([quantumVal] if quantumVal is not None else []) +
960960
qubitsList).result
961961
quake.ExpPauliOp([], [thetaVal], [], [quantumVal],
962962
pauli=pauliWordVal)

python/tests/builder/test_kernel_builder.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,6 +1083,49 @@ def test_exp_pauli():
10831083
kernel.exp_pauli(theta, qubits, invalidOp)
10841084

10851085

1086+
def test_exp_pauli_register_and_qubits():
1087+
"""Test that exp_pauli correctly concatenates a register with
1088+
individual qubits (regression test for operator precedence fix)."""
1089+
cudaq.reset_target()
1090+
1091+
# Case 1: register + individual qubit
1092+
kernel = cudaq.make_kernel()
1093+
qreg = kernel.qalloc(2)
1094+
q_extra = kernel.qalloc()
1095+
kernel.exp_pauli(1.0, qreg, q_extra, 'XXX')
1096+
ir = str(kernel)
1097+
assert 'quake.concat' in ir, \
1098+
"exp_pauli should concat register and individual qubits"
1099+
1100+
# Case 2: register + multiple individual qubits
1101+
kernel = cudaq.make_kernel()
1102+
qreg = kernel.qalloc(2)
1103+
q0 = kernel.qalloc()
1104+
q1 = kernel.qalloc()
1105+
kernel.exp_pauli(0.5, qreg, q0, q1, 'XXYY')
1106+
ir = str(kernel)
1107+
assert 'quake.concat' in ir, \
1108+
"exp_pauli should concat register and multiple individual qubits"
1109+
1110+
# Case 3: individual qubits only (no register) should still work
1111+
kernel = cudaq.make_kernel()
1112+
q0 = kernel.qalloc()
1113+
q1 = kernel.qalloc()
1114+
kernel.exp_pauli(1.0, q0, q1, 'XX')
1115+
ir = str(kernel)
1116+
assert 'quake.concat' in ir
1117+
1118+
# Case 4: register only (no individual qubits) should still work
1119+
kernel = cudaq.make_kernel()
1120+
qreg = kernel.qalloc(2)
1121+
kernel.exp_pauli(1.0, qreg, 'XX')
1122+
counts = cudaq.sample(kernel)
1123+
assert '00' in counts
1124+
assert '11' in counts
1125+
assert not '01' in counts
1126+
assert not '10' in counts
1127+
1128+
10861129
def test_givens_rotation_op():
10871130
cudaq.reset_target()
10881131
angle = 0.2

0 commit comments

Comments
 (0)