Skip to content

fix(transpiler): decompose cy and u3 in qrisp_to_cirq - #1536

Draft
ryanhill1 wants to merge 4 commits into
mainfrom
fix/qrisp-cirq-cy-u3
Draft

ryanhill1 wants to merge 4 commits into
mainfrom
fix/qrisp-cirq-cy-u3

Conversation

@ryanhill1

@ryanhill1 ryanhill1 commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

qrisp_to_cirq raised on any circuit with cy or u3. Qrisp's Cirq converter has no mapping for either and can't decompose them. qiskit_to_qrisp keeps cy in its basis and lowers sdg, tdg, p and u1 to u3, so ordinary Qiskit circuits failed on this edge.

Both are now rewritten before to_cirq():

  • u3(θ, φ, λ) becomes rz(λ) ry(θ) rz(φ) plus its global phase.
  • cy becomes s_dg, cx, s on the target, with the control conjugated by X when it is open (ctrl_state="0").

Composite gates (to_gate()) that contain a cy or u3 are inlined first. Qrisp's converter would otherwise inline them itself after the rewrite, and the nested gate would still raise. Other composites are left for the converter, as before.

Not covered: a composite under a control (to_gate().control(1)) that contains cy becomes a ccy, which qrisp's own transpile() decomposes wrongly. That's an upstream qrisp bug and is unchanged from main.

Found by a conversion conformance fuzzer that checks each conversion against an independently computed unitary. The tests compare against textbook matrices.

Qrisp's to_cirq has no mapping for u3 and cannot decompose it, so the
qrisp -> cirq conversion raised on any u3. qiskit_to_qrisp lowers sdg,
tdg, p and u1 to u3, so these failed too; transpile() only succeeded by
falling back to qrisp -> qasm2 -> cirq. Rewrite each u3 as rz-ry-rz plus
its global phase first.
Qrisp's Cirq converter has no mapping for cy and cannot decompose it, so
qrisp_to_cirq raised ValueError on any circuit containing cy, which
qiskit_to_qrisp keeps in its basis. Rewrite cy as s_dg, cx, s on the
target before calling to_cirq(), conjugating the control with X when
the cy has an open control.
@argus-eye

argus-eye Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Argus review

Auto-review is off for this repo. Tick the box below to run a review on this PR.

Running Argus review...

Estimated cost

  • Files changed: 2
  • Diff lines (±): 98
  • Historical avg: ~532.2k tokens · ~$1.12 · across last 20 review(s)

Tip: you can also comment @argus-eye review at any time.

@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Qrisp's Cirq converter inlines composite gates after the cy and u3
rewrites have run, so a cy or u3 inside a to_gate() block still raised.
Inline the composites that contain one first.
@argus-eye

This comment has been minimized.

@argus-eye argus-eye Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Argus · 10/10 — No findings

Argus reviewed 3 files and checked 2 for bugs, security, architecture, and regressions. Custom agent ponytail-review also ran. The diff matches the stated goal.

What this PR does · 6 author checks
  • Fix qrisp_to_cirq failures on cy and u3 by rewriting them before conversion, including when nested in composite gates.
  • Excludes: Fixing controlled composites containing cy that become ccy; qrisp's upstream transpile() decomposition bug remains unchanged.

Author's checks

  • Before to_cirq(), rewrite u3(θ, φ, λ) as rz(λ), ry(θ), rz(φ), preserving its global phase.
  • Before to_cirq(), rewrite cy as s_dg, cx, s on the target.
  • For cy with ctrl_state="0", conjugate the control with X.
  • Inline composite gates containing cy or u3 before rewriting them.
  • Leave other composite gates for Qrisp's converter, as before.
  • Tests compare conversion results against textbook matrices.
usage: 274.9k tokens · 15 stages

Contract: production/full · checked: bug_hunter, security, architecture, regression, single-pass review, ponytail-review · review took 1m21s

Stage Model Tokens Cost
Intent openai/gpt-6.1-sol 3.8k $0.0079
Triage openai/gpt-6.1-sol 6.7k $0.0078
Lead agent openai/gpt-6.1-sol 1.3k $0.0066
Review specialists (10) openai/gpt-6.1-sol 232.7k $0.4872
Review openai/gpt-6.1-sol 27.8k $0.0559
Simulation openai/gpt-6.1-sol 2.7k $0.0081

Dashboard → · @argus-eye help

🧠 Learned: 1 pattern · 1 PR summary · 1 architecture note

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant