-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[core][compiled graphs] Enable visualization tests (#48627)
In #47958 , visualization unit tests were introduced but would not run if CI environment does not have graphvis installed (which was the case). This PR adds the dependency in test-requirements.txt and always run the visualization tests. It also moves visualization tests to a separate file since test_accelerated_dag.py is too large.
- Loading branch information
1 parent
cae5910
commit f4a7c70
Showing
4 changed files
with
174 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
172 changes: 172 additions & 0 deletions
172
python/ray/dag/tests/experimental/test_dag_visualization.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import sys | ||
import ray | ||
import pydot | ||
import os | ||
from ray.dag import InputNode, MultiOutputNode | ||
from ray.tests.conftest import * # noqa | ||
|
||
import pytest | ||
|
||
|
||
def test_visualize_basic(ray_start_regular): | ||
""" | ||
Expect output or dot_source: | ||
MultiOutputNode" fillcolor=yellow shape=rectangle style=filled] | ||
0 -> 1 [label=SharedMemoryType] | ||
1 -> 2 [label=SharedMemoryType] | ||
""" | ||
|
||
@ray.remote | ||
class Actor: | ||
def echo(self, x): | ||
return x | ||
|
||
actor = Actor.remote() | ||
|
||
with InputNode() as i: | ||
dag = actor.echo.bind(i) | ||
|
||
compiled_dag = dag.experimental_compile() | ||
|
||
# Call the visualize method | ||
dot_source = compiled_dag.visualize(return_dot=True) | ||
|
||
graphs = pydot.graph_from_dot_data(dot_source) | ||
graph = graphs[0] | ||
|
||
node_names = {node.get_name() for node in graph.get_nodes()} | ||
edge_pairs = { | ||
(edge.get_source(), edge.get_destination()) for edge in graph.get_edges() | ||
} | ||
|
||
expected_nodes = {"0", "1", "2"} | ||
assert expected_nodes.issubset( | ||
node_names | ||
), f"Expected nodes {expected_nodes} not found." | ||
|
||
expected_edges = {("0", "1"), ("1", "2")} | ||
assert expected_edges.issubset( | ||
edge_pairs | ||
), f"Expected edges {expected_edges} not found." | ||
|
||
compiled_dag.teardown() | ||
|
||
|
||
def test_visualize_multi_return(ray_start_regular): | ||
""" | ||
Expect output or dot_source: | ||
MultiOutputNode" fillcolor=yellow shape=rectangle style=filled] | ||
0 -> 1 [label=SharedMemoryType] | ||
1 -> 2 [label=SharedMemoryType] | ||
1 -> 3 [label=SharedMemoryType] | ||
2 -> 4 [label=SharedMemoryType] | ||
3 -> 4 [label=SharedMemoryType] | ||
""" | ||
|
||
@ray.remote | ||
class Actor: | ||
@ray.method(num_returns=2) | ||
def return_two(self, x): | ||
return x, x + 1 | ||
|
||
actor = Actor.remote() | ||
|
||
with InputNode() as i: | ||
o1, o2 = actor.return_two.bind(i) | ||
dag = MultiOutputNode([o1, o2]) | ||
|
||
compiled_dag = dag.experimental_compile() | ||
|
||
# Get the DOT source | ||
dot_source = compiled_dag.visualize(return_dot=True) | ||
|
||
graphs = pydot.graph_from_dot_data(dot_source) | ||
graph = graphs[0] | ||
|
||
node_names = {node.get_name() for node in graph.get_nodes()} | ||
edge_pairs = { | ||
(edge.get_source(), edge.get_destination()) for edge in graph.get_edges() | ||
} | ||
|
||
expected_nodes = {"0", "1", "2", "3", "4"} | ||
assert expected_nodes.issubset( | ||
node_names | ||
), f"Expected nodes {expected_nodes} not found." | ||
|
||
expected_edges = {("0", "1"), ("1", "2"), ("1", "3"), ("2", "4"), ("3", "4")} | ||
assert expected_edges.issubset( | ||
edge_pairs | ||
), f"Expected edges {expected_edges} not found." | ||
|
||
compiled_dag.teardown() | ||
|
||
|
||
def test_visualize_multi_return2(ray_start_regular): | ||
""" | ||
Expect output or dot_source: | ||
MultiOutputNode" fillcolor=yellow shape=rectangle style=filled] | ||
0 -> 1 [label=SharedMemoryType] | ||
1 -> 2 [label=SharedMemoryType] | ||
1 -> 3 [label=SharedMemoryType] | ||
2 -> 4 [label=SharedMemoryType] | ||
3 -> 5 [label=SharedMemoryType] | ||
4 -> 6 [label=SharedMemoryType] | ||
5 -> 6 [label=SharedMemoryType] | ||
""" | ||
|
||
@ray.remote | ||
class Actor: | ||
@ray.method(num_returns=2) | ||
def return_two(self, x): | ||
return x, x + 1 | ||
|
||
def echo(self, x): | ||
return x | ||
|
||
a = Actor.remote() | ||
b = Actor.remote() | ||
with InputNode() as i: | ||
o1, o2 = a.return_two.bind(i) | ||
o3 = b.echo.bind(o1) | ||
o4 = b.echo.bind(o2) | ||
dag = MultiOutputNode([o3, o4]) | ||
|
||
compiled_dag = dag.experimental_compile() | ||
|
||
# Get the DOT source | ||
dot_source = compiled_dag.visualize(return_dot=True) | ||
|
||
graphs = pydot.graph_from_dot_data(dot_source) | ||
graph = graphs[0] | ||
|
||
node_names = {node.get_name() for node in graph.get_nodes()} | ||
edge_pairs = { | ||
(edge.get_source(), edge.get_destination()) for edge in graph.get_edges() | ||
} | ||
|
||
expected_nodes = {"0", "1", "2", "3", "4", "5", "6"} | ||
assert expected_nodes.issubset( | ||
node_names | ||
), f"Expected nodes {expected_nodes} not found." | ||
|
||
expected_edges = { | ||
("0", "1"), | ||
("1", "2"), | ||
("1", "3"), | ||
("2", "4"), | ||
("3", "5"), | ||
("4", "6"), | ||
("5", "6"), | ||
} | ||
assert expected_edges.issubset( | ||
edge_pairs | ||
), f"Expected edges {expected_edges} not found." | ||
|
||
compiled_dag.teardown() | ||
|
||
|
||
if __name__ == "__main__": | ||
if os.environ.get("PARALLEL_CI"): | ||
sys.exit(pytest.main(["-n", "auto", "--boxed", "-vs", __file__])) | ||
else: | ||
sys.exit(pytest.main(["-sv", __file__])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters