unitaryfund / mitiq

Mitiq is an open source toolkit for implementing error mitigation techniques on most current intermediate-scale quantum computers.
https://mitiq.readthedocs.io
GNU General Public License v3.0
363 stars 160 forks source link

Unexpected behavior of folding functions with Qiskit circuits with barriers #1368

Closed andreamari closed 2 years ago

andreamari commented 2 years ago

Issue Description

Folding functions with Qiskit circuits with barriers and measurements have unexpected behaviors.

How to Reproduce

It is actually quite hard to reproduce. I couldn't find a simple example. So I need to copy and paste a long example.

Code Snippet

qasm_str = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[27];
creg meas[7];
rz(-0.44584217) q[0];
sx q[0];
rz(-0.77267744) q[0];
sx q[0];
rz(-0.094081305) q[0];
sx q[1];
rz(-pi/2) q[1];
rz(-2.6844376) q[2];
sx q[2];
rz(-1.5635481) q[2];
sx q[2];
rz(-3.0981926) q[2];
sx q[3];
rz(-pi) q[3];
sx q[4];
rz(-pi) q[4];
cx q[1],q[4];
sx q[1];
rz(-pi) q[1];
rz(-pi/2) q[4];
cx q[1],q[4];
sx q[1];
rz(pi/2) q[4];
cx q[1],q[4];
rz(0.33520777) q[1];
sx q[1];
rz(-1.9527369) q[1];
sx q[1];
rz(1.7014235) q[1];
cx q[1],q[2];
sx q[1];
rz(-2.5835448) q[1];
rz(-0.48592005) q[2];
cx q[1],q[2];
sx q[1];
rz(0.040485928) q[2];
cx q[1],q[2];
rz(-0.99653316) q[1];
sx q[1];
rz(-0.65776094) q[1];
sx q[1];
rz(-0.70108421) q[1];
rz(0.41004166) q[2];
sx q[2];
rz(-1.7442448) q[2];
sx q[2];
rz(-1.7696931) q[2];
cx q[2],q[3];
sx q[2];
rz(-pi) q[2];
rz(-pi/2) q[3];
cx q[2],q[3];
sx q[2];
rz(pi/2) q[3];
cx q[2],q[3];
rz(-0.86423266) q[2];
sx q[2];
rz(-1.6553097) q[2];
sx q[2];
rz(1.2796108) q[2];
rz(-pi/2) q[3];
sx q[3];
rz(-pi) q[3];
rz(-2.4336851) q[4];
sx q[4];
rz(-1.5884719) q[4];
sx q[4];
rz(-0.47099041) q[4];
rz(2.0837595) q[5];
sx q[5];
rz(-1.9617796) q[5];
sx q[5];
rz(0.23338352) q[5];
cx q[3],q[5];
sx q[3];
rz(-2.7200616) q[3];
rz(-0.60025486) q[5];
cx q[3],q[5];
sx q[3];
rz(0.038229735) q[5];
cx q[3],q[5];
rz(-2.8737974) q[3];
sx q[3];
rz(-2.1366323) q[3];
sx q[3];
rz(-2.2244229) q[3];
rz(-0.24953519) q[5];
sx q[5];
rz(-1.0683472) q[5];
sx q[5];
rz(0.0060743805) q[5];
rz(2.5802381) q[7];
sx q[7];
rz(-1.7513037) q[7];
sx q[7];
rz(-0.94333146) q[7];
cx q[4],q[7];
sx q[4];
rz(-2.8158669) q[4];
rz(-0.74982312) q[7];
cx q[4],q[7];
sx q[4];
rz(0.27223143) q[7];
cx q[4],q[7];
rz(2.386227) q[4];
sx q[4];
rz(-0.4280627) q[4];
sx q[4];
rz(2.8321082) q[4];
cx q[1],q[4];
sx q[1];
rz(-2.987386) q[1];
rz(1.1873903) q[4];
cx q[1],q[4];
sx q[1];
rz(0.22718048) q[4];
cx q[1],q[4];
rz(2.6645448) q[1];
sx q[1];
rz(-0.26697758) q[1];
sx q[1];
rz(1.2147607) q[1];
cx q[1],q[2];
sx q[1];
rz(-pi) q[1];
rz(-pi/2) q[2];
cx q[1],q[2];
sx q[1];
rz(pi/2) q[2];
cx q[1],q[2];
x q[1];
rz(pi/2) q[1];
cx q[0],q[1];
sx q[0];
rz(-2.7433349) q[0];
rz(0.63380325) q[1];
cx q[0],q[1];
sx q[0];
rz(0.52920382) q[1];
cx q[0],q[1];
rz(-1.5233859) q[0];
sx q[0];
rz(-2.4843495) q[0];
sx q[0];
rz(0.60478292) q[0];
rz(-2.1115445) q[1];
sx q[1];
rz(-1.0253475) q[1];
sx q[1];
rz(0.27978993) q[1];
cx q[2],q[3];
sx q[2];
rz(-3.0791301) q[2];
rz(0.87333282) q[3];
cx q[2],q[3];
sx q[2];
rz(0.088881126) q[3];
cx q[2],q[3];
rz(1.5219976) q[2];
sx q[2];
rz(-1.631705) q[2];
sx q[2];
rz(0.35954142) q[2];
rz(-1.8175896) q[3];
sx q[3];
rz(-2.1505428) q[3];
sx q[3];
rz(-1.1323695) q[3];
cx q[3],q[5];
sx q[3];
rz(-3.0920391) q[3];
rz(-2.6372656) q[4];
sx q[4];
rz(-2.0185671) q[4];
sx q[4];
rz(-0.16252862) q[4];
rz(0.40949303) q[5];
cx q[3],q[5];
sx q[3];
rz(0.038894255) q[5];
cx q[3],q[5];
rz(-3.0276894) q[3];
sx q[3];
rz(-1.8523921) q[3];
sx q[3];
rz(-0.37098566) q[3];
rz(0.07527038) q[5];
sx q[5];
rz(-0.89375919) q[5];
sx q[5];
rz(0.053336173) q[5];
rz(-1.6438863) q[7];
sx q[7];
rz(-1.7474178) q[7];
sx q[7];
rz(-2.7224452) q[7];
cx q[4],q[7];
sx q[4];
rz(-pi) q[4];
rz(-pi/2) q[7];
cx q[4],q[7];
sx q[4];
rz(pi/2) q[7];
cx q[4],q[7];
sx q[4];
cx q[1],q[4];
sx q[1];
rz(-2.9818092) q[1];
rz(-0.55396862) q[4];
cx q[1],q[4];
sx q[1];
rz(0.1220359) q[4];
cx q[1],q[4];
rz(-2.6640011) q[1];
sx q[1];
rz(-2.0529781) q[1];
sx q[1];
rz(1.6406003) q[1];
cx q[0],q[1];
sx q[0];
rz(-2.6894655) q[0];
rz(0.45176903) q[1];
cx q[0],q[1];
sx q[0];
rz(0.063943845) q[1];
cx q[0],q[1];
rz(2.8160986) q[0];
sx q[0];
rz(-1.3949633) q[0];
sx q[0];
rz(-2.8980792) q[0];
rz(-0.82516659) q[1];
sx q[1];
rz(-0.63393482) q[1];
sx q[1];
rz(2.361373) q[1];
rz(-2.5005548) q[4];
sx q[4];
rz(-2.1823123) q[4];
sx q[4];
rz(1.760045) q[4];
rz(-pi) q[7];
sx q[7];
rz(-pi/2) q[7];
cx q[4],q[7];
sx q[4];
rz(-3.0350414) q[4];
rz(-0.60771744) q[7];
cx q[4],q[7];
sx q[4];
rz(0.43514075) q[7];
cx q[4],q[7];
rz(-1.6212337) q[4];
sx q[4];
rz(-0.6803142) q[4];
sx q[4];
rz(-2.3557455) q[4];
cx q[1],q[4];
sx q[1];
rz(-2.8060589) q[1];
rz(-1.0180668) q[4];
cx q[1],q[4];
sx q[1];
rz(0.49977125) q[4];
cx q[1],q[4];
rz(-2.6765806) q[1];
sx q[1];
rz(-1.5874058) q[1];
sx q[1];
rz(-2.2773889) q[1];
cx q[0],q[1];
sx q[0];
rz(-pi) q[0];
rz(-pi/2) q[1];
cx q[0],q[1];
sx q[0];
rz(pi/2) q[1];
cx q[0],q[1];
rz(-pi/2) q[0];
rz(-2.4076481) q[1];
sx q[1];
rz(-1.5762631) q[1];
sx q[1];
rz(1.3846421) q[1];
cx q[1],q[2];
sx q[1];
rz(-2.8256033) q[1];
rz(0.95597927) q[2];
cx q[1],q[2];
sx q[1];
rz(0.33838635) q[2];
cx q[1],q[2];
rz(1.1240594) q[1];
sx q[1];
rz(-1.795006) q[1];
sx q[1];
rz(1.8159879) q[1];
rz(-2.4301677) q[2];
sx q[2];
rz(-0.32418168) q[2];
sx q[2];
rz(-0.21502866) q[2];
cx q[2],q[3];
sx q[2];
rz(-pi) q[2];
rz(-pi/2) q[3];
cx q[2],q[3];
sx q[2];
rz(pi/2) q[3];
cx q[2],q[3];
sx q[2];
rz(-pi/2) q[2];
rz(-pi/2) q[3];
sx q[3];
rz(-pi/2) q[3];
cx q[3],q[5];
sx q[3];
rz(-3.0137565) q[3];
rz(2.6810155) q[4];
sx q[4];
rz(-2.6627085) q[4];
sx q[4];
rz(-0.4365053) q[4];
rz(1.1038277) q[5];
cx q[3],q[5];
sx q[3];
rz(0.28253067) q[5];
cx q[3],q[5];
rz(1.9707383) q[3];
sx q[3];
rz(-2.33308) q[3];
sx q[3];
rz(1.1180647) q[3];
rz(1.3001731) q[5];
sx q[5];
rz(-1.0715088) q[5];
sx q[5];
rz(2.8889386) q[5];
rz(-0.66428674) q[7];
sx q[7];
rz(-3.0987542) q[7];
sx q[7];
rz(0.85996155) q[7];
cx q[4],q[7];
sx q[4];
rz(-2.9645672) q[4];
rz(1.1153752) q[7];
cx q[4],q[7];
sx q[4];
rz(0.65000218) q[7];
cx q[4],q[7];
rz(-1.3722798) q[4];
sx q[4];
rz(-1.9629428) q[4];
sx q[4];
rz(0.65877871) q[4];
cx q[1],q[4];
sx q[1];
rz(-pi) q[1];
rz(-pi/2) q[4];
cx q[1],q[4];
sx q[1];
rz(pi/2) q[4];
cx q[1],q[4];
rz(pi/2) q[1];
sx q[1];
rz(pi/2) q[1];
cx q[1],q[2];
sx q[1];
rz(-2.9496813) q[1];
rz(-0.46584363) q[2];
cx q[1],q[2];
sx q[1];
rz(0.056208709) q[2];
cx q[1],q[2];
rz(2.3998871) q[1];
sx q[1];
rz(-0.81655887) q[1];
sx q[1];
rz(-1.1002574) q[1];
rz(-0.60680545) q[2];
sx q[2];
rz(-1.0910933) q[2];
sx q[2];
rz(-0.013476444) q[2];
cx q[2],q[3];
sx q[2];
rz(-2.6875518) q[2];
rz(-0.62049147) q[3];
cx q[2],q[3];
sx q[2];
rz(0.20873278) q[3];
cx q[2],q[3];
rz(-1.1257586) q[2];
sx q[2];
rz(-1.9604997) q[2];
sx q[2];
rz(1.0089056) q[2];
rz(-0.91418806) q[3];
sx q[3];
rz(-1.819614) q[3];
sx q[3];
rz(-2.6069412) q[3];
cx q[3],q[5];
sx q[3];
rz(-pi) q[3];
sx q[4];
rz(-pi) q[4];
rz(-pi/2) q[5];
cx q[3],q[5];
sx q[3];
rz(pi/2) q[5];
cx q[3],q[5];
rz(-pi/2) q[3];
sx q[3];
rz(-pi) q[3];
cx q[2],q[3];
sx q[2];
rz(-pi) q[2];
rz(-pi/2) q[3];
cx q[2],q[3];
sx q[2];
rz(pi/2) q[3];
cx q[2],q[3];
rz(-pi/2) q[2];
sx q[2];
rz(-pi/2) q[3];
sx q[3];
rz(-pi/2) q[3];
rz(-pi/2) q[5];
sx q[5];
rz(-pi/2) q[5];
rz(1.8841202) q[7];
sx q[7];
rz(-0.62833121) q[7];
sx q[7];
rz(-0.20717257) q[7];
cx q[4],q[7];
sx q[4];
rz(-3.015812) q[4];
rz(1.127538) q[7];
cx q[4],q[7];
sx q[4];
rz(0.25337837) q[7];
cx q[4],q[7];
rz(1.4240771) q[4];
sx q[4];
rz(-1.9947326) q[4];
sx q[4];
rz(2.3635867) q[4];
cx q[1],q[4];
sx q[1];
rz(-pi) q[1];
rz(-pi/2) q[4];
cx q[1],q[4];
sx q[1];
rz(pi/2) q[4];
cx q[1],q[4];
rz(-pi/2) q[1];
sx q[1];
rz(-pi) q[1];
cx q[0],q[1];
sx q[0];
rz(-2.992964) q[0];
rz(1.0718647) q[1];
cx q[0],q[1];
sx q[0];
rz(0.30774833) q[1];
cx q[0],q[1];
rz(-1.902176) q[0];
sx q[0];
rz(-1.2472829) q[0];
sx q[0];
rz(1.9516489) q[0];
rz(-2.3700319) q[1];
sx q[1];
rz(-2.2634857) q[1];
sx q[1];
rz(-2.3879735) q[1];
sx q[4];
rz(pi/2) q[4];
rz(0.61997579) q[7];
sx q[7];
rz(-1.516115) q[7];
sx q[7];
rz(3.0814177) q[7];
cx q[4],q[7];
sx q[4];
rz(-pi) q[4];
rz(-pi/2) q[7];
cx q[4],q[7];
sx q[4];
rz(pi/2) q[7];
cx q[4],q[7];
rz(-pi/2) q[4];
sx q[4];
rz(-pi) q[4];
cx q[1],q[4];
sx q[1];
rz(-pi) q[1];
rz(-pi/2) q[4];
cx q[1],q[4];
sx q[1];
rz(pi/2) q[4];
cx q[1],q[4];
rz(pi/2) q[1];
cx q[1],q[2];
sx q[1];
rz(-3.0278713) q[1];
rz(1.0464188) q[2];
cx q[1],q[2];
sx q[1];
rz(0.12810704) q[2];
cx q[1],q[2];
rz(-0.839075) q[1];
sx q[1];
rz(-2.6621513) q[1];
sx q[1];
rz(2.4528246) q[1];
rz(-2.6838979) q[2];
sx q[2];
rz(-1.3424517) q[2];
sx q[2];
rz(-2.441755) q[2];
rz(-pi/2) q[4];
sx q[4];
rz(-pi/2) q[4];
rz(-pi/2) q[7];
sx q[7];
rz(-pi/2) q[7];
barrier q[14],q[11],q[17],q[20],q[26],q[0],q[23],q[4],q[9],q[6],q[12],q[15],q[21],q[18],q[24],q[1],q[3],q[5],q[10],q[16],q[13],q[19],q[22],q[25],q[2],q[7],q[8];
measure q[0] -> meas[0];
measure q[1] -> meas[1];
measure q[2] -> meas[2];
measure q[4] -> meas[3];
measure q[5] -> meas[4];
measure q[7] -> meas[5];
measure q[3] -> meas[6];
"""
circuit = QuantumCircuit.from_qasm_str(qasm_str)
folded_circuit_wrong = zne.scaling.fold_gates_at_random(circuit, 1.0)

circuit_without_barriers = RemoveBarriers()(circuit)
folded_circuit_correct = zne.scaling.fold_gates_at_random(circuit_without_barriers, 1.0)

The bug is that, in folded_circuit_wrong, the operations applied to qubit q[7] are erroneously moved to q[6].

Solution

For some reason the problem doesn't happen if barriers are manually removed. So there could be some problem with how Mitiq remove barriers.

So, until this bug is fixed, a workaround is to apply circuit_without_barriers = RemoveBarriers()(circuit) before folding.

Environment Context

Mitiq: A Python toolkit for implementing error mitigation on quantum computers
==============================================================================
Authored by: Mitiq team, 2020 & later (https://github.com/unitaryfund/mitiq)

Mitiq Version:  0.17.0dev

Core Dependencies
-----------------
Cirq Version:   0.14.1
NumPy Version:  1.20.3
SciPy Version:  1.7.3

Optional Dependencies
---------------------
PyQuil Version: 3.0.1
Qiskit Version: 0.36.2
Braket Version: 1.25.2

Python Version: 3.7.7
Platform Info:  Linux (x86_64)
rmlarose commented 2 years ago

A simpler example of the unexpected behavior was found in https://github.com/unitaryfund/mitiq/pull/1369#issue-1285873175, copied below.

test_circuit_qiskit = QuantumCircuit(4)
test_circuit_qiskit.x(0)
test_circuit_qiskit.x(2)
test_circuit_qiskit.barrier(0,1,2)
test_folded = zne.scaling.fold_gates_at_random(test_circuit_qiskit, 1.0)
print(f"Input circuit:\n{test_circuit_qiskit}")
print(f"Folded circuit:\n{test_folded}")
Input circuit:
     ┌───┐ ░ 
q_0: ┤ X ├─░─
     └───┘ ░ 
q_1: ──────░─
     ┌───┐ ░ 
q_2: ┤ X ├─░─
     ├───┤ ░ 
q_3: ┤ I ├───
     └───┘   
Folded circuit:
     ┌───┐
q_0: ┤ X ├
     ├───┤
q_1: ┤ X ├
     ├───┤
q_2: ┤ I ├
     └───┘
q_3: ─────