`tfq_ps_decompose` corrupts `PhasedISwapPowGate` when `exponent` is numeric and `phase_exponent` is symbolic

Đang mở Phù hợp với người mới
#1,140 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
78/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python, tensorflow
Lĩnh vực
backend, machine-learning

Hướng nghiên cứu

Đọc tensorflow_quantum/core/ops/tfq_ps_decompose_op.cc, đặc biệt là getOpForISP và vị trí gọi tfq_ps_decompose trong TfqPsDecomposeOp::Compute. So sánh cách hàm này xử lý số mũ ký hiệu và số với getOpForPXP, getOpForPISP và getOpForFSIM. Tái hiện sự cố bằng mạch và ví dụ phân giải tham số được cung cấp; hoàn thành khi các thao tác sau phân rã giữ nguyên số mũ số chính xác và được phân giải mà không gặp lỗi đã báo cáo.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

area/c++ area/core kind/bug-report

In TfqPsDecomposeOp::Compute (tensorflow_quantum/core/ops/tfq_ps_decompose_op.cc, lines 75–97), a PISP (cirq.PhasedISwapPowGate) operation is decomposed whenever either exponent or phase_exponent is symbolic (Arg::ArgCase::kSymbol):

if (exponent.arg_case() == Arg::ArgCase::kSymbol ||
    phase_exponent.arg_case() == Arg::ArgCase::kSymbol) {
  // Decompose cirq.PhasedISwapPowGate only if it is
  // parameterized.
  num_extra_moments = 5;
  Operation new_op;

  new_op = getOpForPISP(cur_op, 0, 0);
  cur_moment.mutable_operations()->at(k) = new_op;
  new_op = getOpForPISP(cur_op, 1, 1);
  *temp_moment_list[0].add_operations() = new_op;
  new_op = getOpForISP(cur_op, "XXP", exponent.symbol());
  *temp_moment_list[1].add_operations() = new_op;
  new_op = getOpForISP(cur_op, "YYP", exponent.symbol());
  *temp_moment_list[2].add_operations() = new_op;
  new_op = getOpForPISP(cur_op, 1, 0);
  *temp_moment_list[3].add_operations() = new_op;
  new_op = getOpForPISP(cur_op, 0, 1);
  *temp_moment_list[4].add_operations() = new_op;
}

However, getOpForISP (lines 164–187) was written for ISP, where exponent is guaranteed to be symbolic, and unconditionally writes new_op_map["exponent"].set_symbol(symbol).

When phase_exponent is a sympy.Symbol and exponent is a numeric constant (Arg::ArgCase::kArgValue — including Cirq's default exponent=1.0, or any non-unit float such as 0.5):

  1. exponent.symbol() evaluates to "" (empty string), and exponent.arg_value().float_value() is ignored.
  2. The decomposed XXP and YYP operations receive a symbolic exponent with empty symbol name "" (sympy.Symbol('') after deserialization) instead of a numeric float -0.5 * exponent.arg_value().float_value().
  3. Resolving circuit parameters leaves unresolved sympy.Symbol('') expressions on the XXPowGate and YYPowGate operations, corrupting the decomposed circuit and breaking ParameterShift differentiation whenever PhasedISwapPowGate has a symbolic phase_exponent and numeric exponent.
Minimal Reproduction
import cirq
import sympy
import tensorflow_quantum as tfq
from tensorflow_quantum.core.ops import tfq_ps_util_ops

q0, q1 = cirq.GridQubit.rect(1, 2)
beta = sympy.Symbol("beta")

# Numeric exponent with symbolic phase_exponent.
circuit = cirq.Circuit(
    cirq.PhasedISwapPowGate(phase_exponent=beta, exponent=0.5).on(q0, q1)
)

decomposed_tensor = tfq_ps_util_ops.tfq_ps_decompose(
    tfq.convert_to_tensor([circuit])
)
decomposed_circuit = tfq.from_tensor(decomposed_tensor)[0]
print(decomposed_circuit)

# Raises TypeError because XXPowGate and YYPowGate contain sympy.Symbol('').
cirq.unitary(cirq.resolve_parameters(decomposed_circuit, {"beta": 0.72}))

Observed decomposed circuit:

(0, 0): ───Z^beta───────────────XX───────────YY───────────Z^(-beta)────────────
                                │            │
(0, 1): ────────────Z^(-beta)───XX^(-0.5*)───YY^(-0.5*)───────────────Z^beta───
Possible Fix

Update getOpForISP to read exponent from cur_op directly (or accept const Arg& instead of std::string symbol) and switch on exponent.arg_case(), consistent with getOpForPXP, getOpForPISP, and getOpForFSIM: keep set_symbol(...) and exponent_scalar = -0.5 * cur_exponent_scalar for Arg::ArgCase::kSymbol, and set exponent to -0.5 * exponent.arg_value().float_value() with exponent_scalar = 1.0 for Arg::ArgCase::kArgValue.

Ngôn ngữ chính
Python
Star
2.2k
Fork
674
Merge trung bình
1 ngày 14 giờ
Pull request đã merge (30 ngày)
5

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của tensorflow/quantum

Tất cả issue của tensorflow/quantum

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.