Fix pass-manager drawing tests for pydot 3.0 (#12775)

* Fix pass-manager drawing tests for pydot 3.0

Two changes in pydot 3 changed the reference output:

1. previously, attributes were sorted before being output.  Pydot 3
   stores them in declaration order.  Here, we sort our attributes to
   maintain the closest behaviour between the two versions.

2. Text fields (like `label`) that contain special characters now have
   their values enclosed in quote marks.  This is a difference between
   the two versions, and we update the reference files to the new
   version since that's what we'll be using in CI.

Qiskit is still compatible with pydot 2 in general usage, it's just our
tests that are a little more tied to the current version.

* Add test-only constraint on pydot
This commit is contained in:
Jake Lishman 2024-07-16 14:24:21 +01:00 committed by GitHub
parent 1191fcbc72
commit c3b468c832
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 34 additions and 26 deletions

View File

@ -13,3 +13,9 @@ scipy==1.13.1; python_version=='3.12'
# `macos_11_7` platform tag. This should be purely a CI artefact, and not
# affect local usage.
z3-solver==4.12.2.0; platform_system=="Darwin"
# There are minor differences in output between pydot 2 and pydot 3 for
# things like the pass-manager drawer. This is totally fine for general
# usage, but our test suite uses an exact reference file that uses the
# pydot 3 output, so we need to enforce that during tests.
pydot>=3.0.0

View File

@ -176,7 +176,7 @@ def staged_pass_manager_drawer(pass_manager, filename=None, style=None, raw=Fals
stage = getattr(pass_manager, st)
if stage is not None:
stagegraph = pydot.Cluster(str(st), label=str(st), fontname="helvetica", labeljust="l")
stagegraph = pydot.Cluster(str(st), fontname="helvetica", label=str(st), labeljust="l")
for controller_group in stage.to_flow_controller().tasks:
subgraph, component_id, prev_node = draw_subgraph(
controller_group, component_id, style, prev_node, idx
@ -201,7 +201,7 @@ def draw_subgraph(controller_group, component_id, style, prev_node, idx):
label += f"{controller_group.__class__.__name__}"
# create the subgraph for this controller
subgraph = pydot.Cluster(str(component_id), label=label, fontname="helvetica", labeljust="l")
subgraph = pydot.Cluster(str(component_id), fontname="helvetica", label=label, labeljust="l")
component_id += 1
if isinstance(controller_group, BaseController):
@ -233,19 +233,19 @@ def draw_subgraph(controller_group, component_id, style, prev_node, idx):
# TODO recursively inject subgraph into subgraph
node = pydot.Node(
str(component_id),
label="Nested flow controller",
color="k",
shape="rectangle",
fontname="helvetica",
label="Nested flow controller",
shape="rectangle",
)
else:
# label is the name of the pass
node = pydot.Node(
str(component_id),
label=str(type(task).__name__),
color=_get_node_color(task, style),
shape="rectangle",
fontname="helvetica",
label=str(type(task).__name__),
shape="rectangle",
)
subgraph.add_node(node)
@ -268,12 +268,12 @@ def draw_subgraph(controller_group, component_id, style, prev_node, idx):
input_node = pydot.Node(
component_id,
label=arg,
color="black",
shape="ellipse",
fontsize=10,
style=nd_style,
fontname="helvetica",
fontsize=10,
label=arg,
shape="ellipse",
style=nd_style,
)
subgraph.add_node(input_node)
component_id += 1

View File

@ -13,7 +13,7 @@ fontname=helvetica;
label="[1] ConditionalController";
labeljust=l;
4 [color=red, fontname=helvetica, label=TrivialLayout, shape=rectangle];
5 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
5 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
5 -> 4;
1 -> 4;
}
@ -23,7 +23,7 @@ fontname=helvetica;
label="[2] ";
labeljust=l;
7 [color=red, fontname=helvetica, label=FullAncillaAllocation, shape=rectangle];
8 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
8 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
8 -> 7;
4 -> 7;
}
@ -41,13 +41,13 @@ fontname=helvetica;
label="[4] ";
labeljust=l;
12 [color=blue, fontname=helvetica, label=BasisTranslator, shape=rectangle];
13 [color=black, fontname=helvetica, fontsize=10, label=equivalence_library, shape=ellipse, style=solid];
13 [color=black, fontname=helvetica, fontsize=10, label="equivalence_library", shape=ellipse, style=solid];
13 -> 12;
14 [color=black, fontname=helvetica, fontsize=10, label=target_basis, shape=ellipse, style=solid];
14 [color=black, fontname=helvetica, fontsize=10, label="target_basis", shape=ellipse, style=solid];
14 -> 12;
15 [color=black, fontname=helvetica, fontsize=10, label=target, shape=ellipse, style=dashed];
15 -> 12;
16 [color=black, fontname=helvetica, fontsize=10, label=min_qubits, shape=ellipse, style=dashed];
16 [color=black, fontname=helvetica, fontsize=10, label="min_qubits", shape=ellipse, style=dashed];
16 -> 12;
10 -> 12;
}
@ -57,9 +57,9 @@ fontname=helvetica;
label="[5] ";
labeljust=l;
18 [color=red, fontname=helvetica, label=CheckMap, shape=rectangle];
19 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
19 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
19 -> 18;
20 [color=black, fontname=helvetica, fontsize=10, label=property_set_field, shape=ellipse, style=dashed];
20 [color=black, fontname=helvetica, fontsize=10, label="property_set_field", shape=ellipse, style=dashed];
20 -> 18;
12 -> 18;
}
@ -79,7 +79,7 @@ fontname=helvetica;
label="[7] ";
labeljust=l;
25 [color=blue, fontname=helvetica, label=GateDirection, shape=rectangle];
26 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
26 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
26 -> 25;
27 [color=black, fontname=helvetica, fontsize=10, label=target, shape=ellipse, style=dashed];
27 -> 25;

View File

@ -13,7 +13,7 @@ fontname=helvetica;
label="[1] ConditionalController";
labeljust=l;
4 [color=red, fontname=helvetica, label=TrivialLayout, shape=rectangle];
5 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
5 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
5 -> 4;
1 -> 4;
}
@ -23,7 +23,7 @@ fontname=helvetica;
label="[2] ";
labeljust=l;
7 [color=red, fontname=helvetica, label=FullAncillaAllocation, shape=rectangle];
8 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
8 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
8 -> 7;
4 -> 7;
}
@ -41,13 +41,13 @@ fontname=helvetica;
label="[4] ";
labeljust=l;
12 [color=blue, fontname=helvetica, label=BasisTranslator, shape=rectangle];
13 [color=black, fontname=helvetica, fontsize=10, label=equivalence_library, shape=ellipse, style=solid];
13 [color=black, fontname=helvetica, fontsize=10, label="equivalence_library", shape=ellipse, style=solid];
13 -> 12;
14 [color=black, fontname=helvetica, fontsize=10, label=target_basis, shape=ellipse, style=solid];
14 [color=black, fontname=helvetica, fontsize=10, label="target_basis", shape=ellipse, style=solid];
14 -> 12;
15 [color=black, fontname=helvetica, fontsize=10, label=target, shape=ellipse, style=dashed];
15 -> 12;
16 [color=black, fontname=helvetica, fontsize=10, label=min_qubits, shape=ellipse, style=dashed];
16 [color=black, fontname=helvetica, fontsize=10, label="min_qubits", shape=ellipse, style=dashed];
16 -> 12;
10 -> 12;
}
@ -57,9 +57,9 @@ fontname=helvetica;
label="[5] ";
labeljust=l;
18 [color=green, fontname=helvetica, label=CheckMap, shape=rectangle];
19 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
19 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
19 -> 18;
20 [color=black, fontname=helvetica, fontsize=10, label=property_set_field, shape=ellipse, style=dashed];
20 [color=black, fontname=helvetica, fontsize=10, label="property_set_field", shape=ellipse, style=dashed];
20 -> 18;
12 -> 18;
}
@ -79,7 +79,7 @@ fontname=helvetica;
label="[7] ";
labeljust=l;
25 [color=blue, fontname=helvetica, label=GateDirection, shape=rectangle];
26 [color=black, fontname=helvetica, fontsize=10, label=coupling_map, shape=ellipse, style=solid];
26 [color=black, fontname=helvetica, fontsize=10, label="coupling_map", shape=ellipse, style=solid];
26 -> 25;
27 [color=black, fontname=helvetica, fontsize=10, label=target, shape=ellipse, style=dashed];
27 -> 25;

View File

@ -42,6 +42,8 @@ from .visualization import QiskitVisualizationTestCase, path_to_diagram_referenc
class TestPassManagerDrawer(QiskitVisualizationTestCase):
"""Qiskit pass manager drawer tests."""
maxDiff = None
def setUp(self):
super().setUp()
coupling = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]