mirror of https://github.com/Qiskit/qiskit.git
458 lines
14 KiB
Python
458 lines
14 KiB
Python
# This code is part of Qiskit.
|
|
#
|
|
# (C) Copyright IBM 2017, 2024.
|
|
#
|
|
# This code is licensed under the Apache License, Version 2.0. You may
|
|
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
|
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
|
#
|
|
# Any modifications or derivative works of this code must retain this
|
|
# copyright notice, and modified files need to carry a notice indicating
|
|
# that they have been altered from the originals.
|
|
|
|
"""A test for visualizing device coupling maps"""
|
|
import unittest
|
|
|
|
from io import BytesIO
|
|
from ddt import ddt, data
|
|
from qiskit.providers.fake_provider import (
|
|
Fake5QV1,
|
|
Fake20QV1,
|
|
Fake7QPulseV1,
|
|
GenericBackendV2,
|
|
)
|
|
from qiskit.visualization import (
|
|
plot_gate_map,
|
|
plot_coupling_map,
|
|
plot_circuit_layout,
|
|
plot_error_map,
|
|
)
|
|
from qiskit.utils import optionals
|
|
from qiskit import QuantumRegister, QuantumCircuit
|
|
from qiskit.transpiler.layout import Layout, TranspileLayout
|
|
from .visualization import path_to_diagram_reference, QiskitVisualizationTestCase
|
|
from ..legacy_cmaps import KYOTO_CMAP, MUMBAI_CMAP
|
|
|
|
if optionals.HAS_MATPLOTLIB:
|
|
import matplotlib.pyplot as plt
|
|
if optionals.HAS_PIL:
|
|
from PIL import Image
|
|
|
|
|
|
@ddt
|
|
@unittest.skipUnless(optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_PIL, "PIL not available")
|
|
@unittest.skipUnless(optionals.HAS_SEABORN, "seaborn not available")
|
|
class TestGateMap(QiskitVisualizationTestCase):
|
|
# pylint: disable=possibly-used-before-assignment
|
|
"""visual tests for plot_gate_map"""
|
|
|
|
backends = [Fake5QV1(), Fake20QV1(), Fake7QPulseV1()]
|
|
|
|
@data(*backends)
|
|
@unittest.skipIf(not optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_GRAPHVIZ, "Graphviz not installed")
|
|
def test_plot_gate_map(self, backend):
|
|
"""tests plotting of gate map of a device (20 qubit, 7 qubit, and 5 qubit)"""
|
|
n = backend.configuration().n_qubits
|
|
img_ref = path_to_diagram_reference(str(n) + "bit_quantum_computer.png")
|
|
fig = plot_gate_map(backend)
|
|
with BytesIO() as img_buffer:
|
|
fig.savefig(img_buffer, format="png")
|
|
img_buffer.seek(0)
|
|
self.assertImagesAreEqual(Image.open(img_buffer), img_ref, 0.05)
|
|
plt.close(fig)
|
|
|
|
@data(*backends)
|
|
@unittest.skipIf(not optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_GRAPHVIZ, "Graphviz not installed")
|
|
def test_plot_circuit_layout(self, backend):
|
|
"""tests plot_circuit_layout for each device"""
|
|
layout_length = int(backend._configuration.n_qubits / 2)
|
|
qr = QuantumRegister(layout_length, "qr")
|
|
circuit = QuantumCircuit(qr)
|
|
circuit._layout = TranspileLayout(
|
|
Layout({qr[i]: i * 2 for i in range(layout_length)}),
|
|
{qubit: index for index, qubit in enumerate(circuit.qubits)},
|
|
)
|
|
circuit._layout.initial_layout.add_register(qr)
|
|
n = backend.configuration().n_qubits
|
|
img_ref = path_to_diagram_reference(str(n) + "_plot_circuit_layout.png")
|
|
fig = plot_circuit_layout(circuit, backend)
|
|
with BytesIO() as img_buffer:
|
|
fig.savefig(img_buffer, format="png")
|
|
img_buffer.seek(0)
|
|
self.assertImagesAreEqual(Image.open(img_buffer), img_ref, 0.05)
|
|
plt.close(fig)
|
|
|
|
@unittest.skipIf(not optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_GRAPHVIZ, "Graphviz not installed")
|
|
def test_plot_gate_map_no_backend(self):
|
|
"""tests plotting of gate map without a device"""
|
|
n_qubits = 8
|
|
coupling_map = [[0, 1], [1, 2], [2, 3], [3, 5], [4, 5], [5, 6], [2, 4], [6, 7]]
|
|
qubit_coordinates = [[0, 1], [1, 1], [1, 0], [1, 2], [2, 0], [2, 2], [2, 1], [3, 1]]
|
|
img_ref = path_to_diagram_reference(str(n_qubits) + "qubits.png")
|
|
fig = plot_coupling_map(
|
|
num_qubits=n_qubits, qubit_coordinates=qubit_coordinates, coupling_map=coupling_map
|
|
)
|
|
with BytesIO() as img_buffer:
|
|
fig.savefig(img_buffer, format="png")
|
|
img_buffer.seek(0)
|
|
self.assertImagesAreEqual(Image.open(img_buffer), img_ref, 0.2)
|
|
plt.close(fig)
|
|
|
|
@unittest.skipIf(not optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_GRAPHVIZ, "Graphviz not installed")
|
|
@unittest.skipUnless(optionals.HAS_SEABORN, "Seaborn not installed")
|
|
def test_plot_error_map_backend_v1(self):
|
|
"""Test plotting error map with fake backend v1."""
|
|
backend = GenericBackendV2(
|
|
num_qubits=27,
|
|
coupling_map=MUMBAI_CMAP,
|
|
)
|
|
img_ref = path_to_diagram_reference("fake_27_q_error.png")
|
|
fig = plot_error_map(backend)
|
|
with BytesIO() as img_buffer:
|
|
fig.savefig(img_buffer, format="png")
|
|
img_buffer.seek(0)
|
|
self.assertImagesAreEqual(Image.open(img_buffer), img_ref, 0.05)
|
|
plt.close(fig)
|
|
|
|
@unittest.skipIf(not optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_GRAPHVIZ, "Graphviz not installed")
|
|
@unittest.skipUnless(optionals.HAS_SEABORN, "Seaborn not installed")
|
|
def test_plot_error_map_backend_v2(self):
|
|
"""Test plotting error map with fake backend v2."""
|
|
coupling_map = MUMBAI_CMAP
|
|
backend = GenericBackendV2(
|
|
num_qubits=27,
|
|
coupling_map=coupling_map,
|
|
)
|
|
img_ref = path_to_diagram_reference("fake_27_q_v2_error.png")
|
|
fig = plot_error_map(backend)
|
|
with BytesIO() as img_buffer:
|
|
fig.savefig(img_buffer, format="png")
|
|
img_buffer.seek(0)
|
|
self.assertImagesAreEqual(Image.open(img_buffer), img_ref, 0.05)
|
|
plt.close(fig)
|
|
|
|
@unittest.skipIf(not optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_GRAPHVIZ, "Graphviz not installed")
|
|
@unittest.skipUnless(optionals.HAS_SEABORN, "Seaborn not installed")
|
|
def test_plot_error_map_over_100_qubit(self):
|
|
"""Test plotting error map with large fake backend."""
|
|
coupling_map = KYOTO_CMAP
|
|
backend = GenericBackendV2(num_qubits=127, coupling_map=coupling_map, seed=42)
|
|
img_ref = path_to_diagram_reference("fake_127_q_error.png")
|
|
fig = plot_error_map(backend)
|
|
with BytesIO() as img_buffer:
|
|
fig.savefig(img_buffer, format="png")
|
|
img_buffer.seek(0)
|
|
self.assertImagesAreEqual(Image.open(img_buffer), img_ref, 0.05)
|
|
plt.close(fig)
|
|
|
|
@unittest.skipIf(not optionals.HAS_MATPLOTLIB, "matplotlib not available.")
|
|
@unittest.skipUnless(optionals.HAS_GRAPHVIZ, "Graphviz not installed")
|
|
@unittest.skipUnless(optionals.HAS_SEABORN, "Seaborn not installed")
|
|
def test_plot_error_map_over_100_qubit_backend_v2(self):
|
|
"""Test plotting error map with large fake backendv2."""
|
|
coupling_map = [
|
|
[0, 1],
|
|
[0, 14],
|
|
[1, 0],
|
|
[1, 2],
|
|
[2, 1],
|
|
[2, 3],
|
|
[3, 2],
|
|
[3, 4],
|
|
[4, 3],
|
|
[4, 5],
|
|
[4, 15],
|
|
[5, 4],
|
|
[5, 6],
|
|
[6, 5],
|
|
[6, 7],
|
|
[7, 6],
|
|
[7, 8],
|
|
[8, 7],
|
|
[8, 16],
|
|
[9, 10],
|
|
[10, 9],
|
|
[10, 11],
|
|
[11, 10],
|
|
[11, 12],
|
|
[12, 11],
|
|
[12, 13],
|
|
[12, 17],
|
|
[13, 12],
|
|
[14, 0],
|
|
[14, 18],
|
|
[15, 4],
|
|
[15, 22],
|
|
[16, 8],
|
|
[16, 26],
|
|
[17, 12],
|
|
[17, 30],
|
|
[18, 14],
|
|
[18, 19],
|
|
[19, 18],
|
|
[19, 20],
|
|
[20, 19],
|
|
[20, 21],
|
|
[20, 33],
|
|
[21, 20],
|
|
[21, 22],
|
|
[22, 15],
|
|
[22, 21],
|
|
[22, 23],
|
|
[23, 22],
|
|
[23, 24],
|
|
[24, 23],
|
|
[24, 25],
|
|
[24, 34],
|
|
[25, 24],
|
|
[25, 26],
|
|
[26, 16],
|
|
[26, 25],
|
|
[26, 27],
|
|
[27, 26],
|
|
[27, 28],
|
|
[28, 27],
|
|
[28, 29],
|
|
[28, 35],
|
|
[29, 28],
|
|
[29, 30],
|
|
[30, 17],
|
|
[30, 29],
|
|
[30, 31],
|
|
[31, 30],
|
|
[31, 32],
|
|
[32, 31],
|
|
[32, 36],
|
|
[33, 20],
|
|
[33, 39],
|
|
[34, 24],
|
|
[34, 43],
|
|
[35, 28],
|
|
[35, 47],
|
|
[36, 32],
|
|
[36, 51],
|
|
[37, 38],
|
|
[37, 52],
|
|
[38, 37],
|
|
[38, 39],
|
|
[39, 33],
|
|
[39, 38],
|
|
[39, 40],
|
|
[40, 39],
|
|
[40, 41],
|
|
[41, 40],
|
|
[41, 42],
|
|
[41, 53],
|
|
[42, 41],
|
|
[42, 43],
|
|
[43, 34],
|
|
[43, 42],
|
|
[43, 44],
|
|
[44, 43],
|
|
[44, 45],
|
|
[45, 44],
|
|
[45, 46],
|
|
[45, 54],
|
|
[46, 45],
|
|
[46, 47],
|
|
[47, 35],
|
|
[47, 46],
|
|
[47, 48],
|
|
[48, 47],
|
|
[48, 49],
|
|
[49, 48],
|
|
[49, 50],
|
|
[49, 55],
|
|
[50, 49],
|
|
[50, 51],
|
|
[51, 36],
|
|
[51, 50],
|
|
[52, 37],
|
|
[52, 56],
|
|
[53, 41],
|
|
[53, 60],
|
|
[54, 45],
|
|
[54, 64],
|
|
[55, 49],
|
|
[55, 68],
|
|
[56, 52],
|
|
[56, 57],
|
|
[57, 56],
|
|
[57, 58],
|
|
[58, 57],
|
|
[58, 59],
|
|
[58, 71],
|
|
[59, 58],
|
|
[59, 60],
|
|
[60, 53],
|
|
[60, 59],
|
|
[60, 61],
|
|
[61, 60],
|
|
[61, 62],
|
|
[62, 61],
|
|
[62, 63],
|
|
[62, 72],
|
|
[63, 62],
|
|
[63, 64],
|
|
[64, 54],
|
|
[64, 63],
|
|
[64, 65],
|
|
[65, 64],
|
|
[65, 66],
|
|
[66, 65],
|
|
[66, 67],
|
|
[66, 73],
|
|
[67, 66],
|
|
[67, 68],
|
|
[68, 55],
|
|
[68, 67],
|
|
[68, 69],
|
|
[69, 68],
|
|
[69, 70],
|
|
[70, 69],
|
|
[70, 74],
|
|
[71, 58],
|
|
[71, 77],
|
|
[72, 62],
|
|
[72, 81],
|
|
[73, 66],
|
|
[73, 85],
|
|
[74, 70],
|
|
[74, 89],
|
|
[75, 76],
|
|
[75, 90],
|
|
[76, 75],
|
|
[76, 77],
|
|
[77, 71],
|
|
[77, 76],
|
|
[77, 78],
|
|
[78, 77],
|
|
[78, 79],
|
|
[79, 78],
|
|
[79, 80],
|
|
[79, 91],
|
|
[80, 79],
|
|
[80, 81],
|
|
[81, 72],
|
|
[81, 80],
|
|
[81, 82],
|
|
[82, 81],
|
|
[82, 83],
|
|
[83, 82],
|
|
[83, 84],
|
|
[83, 92],
|
|
[84, 83],
|
|
[84, 85],
|
|
[85, 73],
|
|
[85, 84],
|
|
[85, 86],
|
|
[86, 85],
|
|
[86, 87],
|
|
[87, 86],
|
|
[87, 88],
|
|
[87, 93],
|
|
[88, 87],
|
|
[88, 89],
|
|
[89, 74],
|
|
[89, 88],
|
|
[90, 75],
|
|
[90, 94],
|
|
[91, 79],
|
|
[91, 98],
|
|
[92, 83],
|
|
[92, 102],
|
|
[93, 87],
|
|
[93, 106],
|
|
[94, 90],
|
|
[94, 95],
|
|
[95, 94],
|
|
[95, 96],
|
|
[96, 95],
|
|
[96, 97],
|
|
[96, 109],
|
|
[97, 96],
|
|
[97, 98],
|
|
[98, 91],
|
|
[98, 97],
|
|
[98, 99],
|
|
[99, 98],
|
|
[99, 100],
|
|
[100, 99],
|
|
[100, 101],
|
|
[100, 110],
|
|
[101, 100],
|
|
[101, 102],
|
|
[102, 92],
|
|
[102, 101],
|
|
[102, 103],
|
|
[103, 102],
|
|
[103, 104],
|
|
[104, 103],
|
|
[104, 105],
|
|
[104, 111],
|
|
[105, 104],
|
|
[105, 106],
|
|
[106, 93],
|
|
[106, 105],
|
|
[106, 107],
|
|
[107, 106],
|
|
[107, 108],
|
|
[108, 107],
|
|
[108, 112],
|
|
[109, 96],
|
|
[110, 100],
|
|
[110, 118],
|
|
[111, 104],
|
|
[111, 122],
|
|
[112, 108],
|
|
[112, 126],
|
|
[113, 114],
|
|
[114, 113],
|
|
[114, 115],
|
|
[115, 114],
|
|
[115, 116],
|
|
[116, 115],
|
|
[116, 117],
|
|
[117, 116],
|
|
[117, 118],
|
|
[118, 110],
|
|
[118, 117],
|
|
[118, 119],
|
|
[119, 118],
|
|
[119, 120],
|
|
[120, 119],
|
|
[120, 121],
|
|
[121, 120],
|
|
[121, 122],
|
|
[122, 111],
|
|
[122, 121],
|
|
[122, 123],
|
|
[123, 122],
|
|
[123, 124],
|
|
[124, 123],
|
|
[124, 125],
|
|
[125, 124],
|
|
[125, 126],
|
|
[126, 112],
|
|
[126, 125],
|
|
]
|
|
backend = GenericBackendV2(num_qubits=127, coupling_map=coupling_map, seed=42)
|
|
img_ref = path_to_diagram_reference("fake_127_q_v2_error.png")
|
|
fig = plot_error_map(backend)
|
|
with BytesIO() as img_buffer:
|
|
fig.savefig(img_buffer, format="png")
|
|
img_buffer.seek(0)
|
|
self.assertImagesAreEqual(Image.open(img_buffer), img_ref, 0.2)
|
|
plt.close(fig)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2)
|