`tfq_ps_decompose` truncates decomposed moments when `PhasedISwapPowGate` shares a `Moment` with `PhasedXPowGate` or `FSimGate`
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 74/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- python, tensorflow
- Domain
- backend, machine-learning, testing-qa
Research direction
Read tensorflow_quantum/core/ops/tfq_ps_decompose_op.cc, especially TfqPsDecomposeOp::Compute around lines 71–147, and inspect the decomposition tests for tfq_ps_decompose. Reproduce the issue with the supplied circuit and compare the original and decomposed unitaries. Done means the output retains all six moments and the decomposed circuit matches the original unitary for the reproducer.
Written by the indexing model from the issue text.
Description
In TfqPsDecomposeOp::Compute (tensorflow_quantum/core/ops/tfq_ps_decompose_op.cc, lines 71–147), each Moment initializes int num_extra_moments = 0; and decomposes parameterized gates across cur_moment plus up to max_buffer_moments = 5 extra moments in temp_moment_list:
PISP(cirq.PhasedISwapPowGate, line 82) populatestemp_moment_list[0..4]and setsnum_extra_moments = 5;.ISP(cirq.ISwapPowGate, line 102) populatestemp_moment_list[0]and guards the update withif (num_extra_moments == 0) num_extra_moments = 1;.PXP(cirq.PhasedXPowGate, line 115) populatestemp_moment_list[0..1]and unconditionally assignsnum_extra_moments = 2;.FSIM(cirq.FSimGate, line 130) populatestemp_moment_list[0..1]and unconditionally assignsnum_extra_moments = 2;.
If a single Moment contains a parameterized PhasedISwapPowGate followed by a parameterized PhasedXPowGate or FSimGate on disjoint qubits, the later PXP or FSIM branch overwrites num_extra_moments from 5 down to 2. When extra moments are appended at lines 142–147, temp_moment_list[2] (YYP), temp_moment_list[3] (ZP), and temp_moment_list[4] (ZP) from the PhasedISwapPowGate decomposition are silently dropped, changing the circuit unitary and producing incorrect ParameterShift gradients.
Minimal Reproduction
import cirq
import numpy as np
import sympy
import tensorflow_quantum as tfq
from tensorflow_quantum.core.ops import tfq_ps_util_ops
q0, q1, q2 = cirq.GridQubit.rect(1, 3)
alpha = sympy.Symbol("alpha")
beta = sympy.Symbol("beta")
circuit = cirq.Circuit(
cirq.Moment(
cirq.PhasedISwapPowGate(phase_exponent=beta, exponent=alpha).on(q0, q1),
cirq.PhasedXPowGate(phase_exponent=beta, exponent=alpha).on(q2),
)
)
decomposed_tensor = tfq_ps_util_ops.tfq_ps_decompose(
tfq.convert_to_tensor([circuit])
)
decomposed_circuit = tfq.from_tensor(decomposed_tensor)[0]
print("Moment count (expected 6, got):", len(decomposed_circuit.moments))
print(decomposed_circuit)
resolver = {"alpha": 0.35, "beta": 0.72}
u_orig = cirq.unitary(cirq.resolve_parameters(circuit, resolver))
u_decomp = cirq.unitary(cirq.resolve_parameters(decomposed_circuit, resolver))
print("Max unitary difference:", np.max(np.abs(u_orig - u_decomp)))
Observed output:
Moment count (expected 6, got): 3
(0, 0): ───Z^beta──────────────────XX────────────────
│
(0, 1): ───────────────Z^(-beta)───XX^(-0.5*alpha)───
(0, 2): ───Z^(-beta)───X^alpha─────Z^beta────────────
Max unitary difference: 1.400898757622091
Possible Fix
Include <algorithm> and update num_extra_moments using std::max across all decomposed gate branches (num_extra_moments = std::max(num_extra_moments, 5); for PISP, 1 for ISP, and 2 for PXP and FSIM) so earlier decompositions in the same Moment are never truncated.
Related: #1140
- Dominant language
- Python
- Stars
- 2.2k
- Forks
- 674
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 5
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from tensorflow/quantum
-
area/c++ area/core kind/bug-report
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
tensorflow/quantum#1140 ·
Maintainers usually reply within 1 day
-
Avoid hard-coding "quantum" in `scripts/` scriptsPossibly taken @openbotgit claimed this 23 days ago. Openarea/devops help wanted no QC knowledge needed priority/before-0.7.7
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
tensorflow/quantum#1082 · 2 comments · 1 reaction ·
Maintainers usually reply within 1 day
-
Bug (likely typo) in `core/serialize/serializer_test.py`Possibly taken @mhucka claimed this 15 days ago. Openarea/serialization area/tests
tensorflow/quantum#1129 · 1 assignee ·
Maintainers usually reply within 1 day
-
Support Keras 3May be free again @rosspeili claimed this 118 days ago, and no pull request is open. Openarea/keras help wanted skill-level/intermediate
tensorflow/quantum#1090 · 5 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
area/circuits priority/after-0.7.7 skill-level/expert
Difficulty 5/5 Over a week Newbie friendliness 25/100
tensorflow/quantum#1087 ·
Maintainers usually reply within 1 day
All issues in tensorflow/quantum
Similar issues
-
release
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
MichaelYcJo/SpecSeal#1535 ·
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
valentinfrlch/ha-llmvision#769 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 1/5 Under an hour Newbie friendliness 75/100
daniel-ospina/tortoise#11937 · 1 comment ·
Maintainers usually reply within 1 day
-
good first issue help wanted python up-for-grabs
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
andrewsiah/agentswarm-data-tasks#238 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
cadence-workflow/cadence-ai-samples#175 ·
Maintainers usually reply within 1 day