Skip to content

Conversation

@yurekami
Copy link

Summary

Fixes #232

This PR fixes the bug where multi-parameter gates (U2, U3, Rot, R, etc.) fail when passing 1D parameters like [0.1, 0.2].

The Problem

import torchquantum as tq

qdev = tq.QuantumDevice(n_wires=2, bsz=5, device="cpu")
tq.u2(qdev, [0], [0.1, 0.2])  # ❌ This was failing

The error occurred because gate_wrapper was transforming 1D params incorrectly:

  • Before: [0.1, 0.2] (shape [2]) → [2, 1] via unsqueeze(-1)
  • Expected: [0.1, 0.2] (shape [2]) → [[0.1, 0.2]] (shape [1, 2])

Multi-parameter gate matrix functions access params as params[:, 0] and params[:, 1], requiring shape [batch, n_params].

The Fix

Changed the dimension handling in gate_wrapper:

  • 1D params: unsqueeze(0) instead of unsqueeze(-1) - adds batch dimension at front
  • 0D params (scalar): unsqueeze(0).unsqueeze(0) - adds both batch and param dimensions

Affected Gates

These gates now work correctly with 1D input for single-batch usage:

  • U2: tq.u2(qdev, [0], [phi, lam])
  • U3: tq.u3(qdev, [0], [theta, phi, lam])
  • Rot: tq.rot(qdev, [0], [phi, theta])
  • R: tq.r(qdev, [0], [theta, phi])
  • XXMinusYY, XXPlusYY: with [theta, beta]
  • CU2, CU3, CRot: controlled versions

Backward Compatibility

The change maintains backward compatibility:

  • 2D batched params [[0.1, 0.2], [0.3, 0.4]] still work as before
  • Single-param gates with 1D input [0.1][[0.1]] still work correctly

Test Plan

  • Run tq.u2(qdev, [0], [0.1, 0.2]) with bsz=1 - should work now
  • Run tq.u3(qdev, [0], [0.1, 0.2, 0.3]) - should work
  • Verify existing tests pass (no regression for single-param gates)
  • Verify batched params [[0.1, 0.2], [0.3, 0.4]] still work

🤖 Generated with Claude Code

Fixes mit-han-lab#232

Previously, when passing 1D parameters like [0.1, 0.2] to multi-parameter
gates (U2, U3, Rot, etc.), the gate_wrapper would transform:
  [0.1, 0.2] (shape [2]) -> [2, 1] via unsqueeze(-1)

This caused errors because multi-parameter gate matrix functions expect
params with shape [batch, n_params], e.g., [1, 2] for U2.

This fix changes the dimension handling:
  - 1D params: unsqueeze(0) instead of unsqueeze(-1)
    [0.1, 0.2] -> [[0.1, 0.2]] with shape [1, 2]
  - 0D params (scalar): unsqueeze(0).unsqueeze(0)
    0.1 -> [[0.1]] with shape [1, 1]

Affected gates that now work correctly with 1D input:
- U2: tq.u2(qdev, [0], [phi, lam])
- U3: tq.u3(qdev, [0], [theta, phi, lam])
- Rot: tq.rot(qdev, [0], [phi, theta])
- R: tq.r(qdev, [0], [theta, phi])
- XXMinusYY, XXPlusYY: with [theta, beta]

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
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.

Bug in U2 gate parameter initialization

1 participant