quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.27k stars 1.01k forks source link

QASM roundtrip cause inconsistent results for a circuit containing YYPowGate or XXPowGate with global shift #6488

Open jiannanWang opened 7 months ago

jiannanWang commented 7 months ago

Description of the issue Below is a circuit containing two gates: a XPowGate and a YYPowGate with global_shift=1.0. After saving the circuit to the QASM string and loading it back as a new circuit, the new circuit has different results from the original circuit. Noticed that the new circuit evaluates to '5', while the original circuit evaluates to '7'.

I further compared the circuit's result state vector with atol=1e-3. It shows that the two circuits have different result state vectors.

How to reproduce the issue

import cirq
from cirq import *
import numpy as np

qr = cirq.LineQubit.range(3)
qc = cirq.Circuit()
qc.append(XPowGate().on(qr[0]))
qc.append(YYPowGate(global_shift=1.0).on(qr[1], qr[2]).controlled_by(qr[0]))

qasm_str = qc.to_qasm()
from cirq.contrib.qasm_import import circuit_from_qasm
new_qc = circuit_from_qasm(qasm_str)

simulator = cirq.Simulator(dtype=np.complex128)
result = simulator.simulate(qc)
st = result.final_state_vector
qc.append(cirq.measure(sorted(qc.all_qubits()), key='result'))
samples = simulator.run(qc, repetitions=5000)
counts = samples.histogram(key='result')
RESULT1 = counts
print(RESULT1)
print(st)

new_simulater = cirq.Simulator(dtype=np.complex128)
new_result = new_simulater.simulate(new_qc)
new_st = new_result.final_state_vector
new_qc.append(cirq.measure(sorted(new_qc.all_qubits()), key='result'))
new_samples = new_simulater.run(new_qc, repetitions=5000)
new_counts = new_samples.histogram(key='result')
RESULT2 = new_counts
print(RESULT2)
print(new_st)
print(cirq.equal_up_to_global_phase(st, new_st, atol=1e-3))
Counter({7: 5000}) [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 1.+0.j] Counter({5: 5000}) [ 2.22044605e-16+1.94289029e-16j 7.85046229e-17-2.35513869e-16j -1.84918018e-16-1.78400039e-16j -4.75349278e-17-2.62973316e-17j 2.77555756e-17+1.66533454e-16j -6.44130305e-17+1.00000000e+00j -6.68634521e-17-2.74068786e-17j -1.55181153e-16+4.12846664e-17j] False

Cirq version You can get the cirq version by printing cirq.__version__. From the command line:

1.3.0

Additional investigation Similar inconsistent results can also be found on a circuit with a XXPowGate with global_shift=1.0. The original circuit evaluates to '7' while the new circuit evaluates to '5'.

Reproduction code:

import cirq
from cirq import *
import numpy as np

qr = cirq.LineQubit.range(3)
qc = cirq.Circuit()

qc.append(YPowGate().on(qr[0]))
qc.append(XXPowGate(global_shift=1.0).on(qr[1], qr[2]).controlled_by(qr[0]))

qasm_str = qc.to_qasm()
from cirq.contrib.qasm_import import circuit_from_qasm
new_qc = circuit_from_qasm(qasm_str)

simulator = cirq.Simulator(dtype=np.complex128)
result = simulator.simulate(qc)
st = result.final_state_vector
qc.append(cirq.measure(sorted(qc.all_qubits()), key='result'))
samples = simulator.run(qc, repetitions=5000)
counts = samples.histogram(key='result')
RESULT1 = counts
print(RESULT1)
print(st)

new_simulater = cirq.Simulator(dtype=np.complex128)
new_result = new_simulater.simulate(new_qc)
new_st = new_result.final_state_vector
new_qc.append(cirq.measure(sorted(new_qc.all_qubits()), key='result'))
new_samples = new_simulater.run(new_qc, repetitions=5000)
new_counts = new_samples.histogram(key='result')
RESULT2 = new_counts
print(RESULT2)
print(new_st)
print(cirq.equal_up_to_global_phase(st, new_st, atol=1e-3))

logs:

Counter({7: 5000}) [0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.+0.j 0.-1.j] Counter({5: 5000}) [ 0.00000000e+00+0.00000000e+00j 0.00000000e+00+0.00000000e+00j 0.00000000e+00+0.00000000e+00j 0.00000000e+00+0.00000000e+00j -7.85046229e-17-1.66533454e-16j -6.47085399e-16+1.00000000e+00j 1.38777878e-17+6.93889390e-17j 4.16333634e-17-1.38777878e-17j] False
pavoljuhas commented 7 months ago

csynque meeting - this looks like a bug, but we need to check if qasm has support for global shift controlled by qubit.

github-actions[bot] commented 6 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 5 months ago

Issue closed due to inactivity.

github-actions[bot] commented 4 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 3 months ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 2 months ago

Issue closed due to inactivity.

github-actions[bot] commented 1 month ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days