.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_how-to/example_visualize_the_operation_dag.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_how-to_example_visualize_the_operation_dag.py: Visualize the operation DAG =========================== When a solver's operation order doesn't match what you expect, render the dependency graph and inspect it directly. The graph package exposes one function for the common case and a pyvis writer for interactive HTML. .. GENERATED FROM PYTHON SOURCE LINES 12-21 Render a single domain's DAG to HTML ------------------------------------ After ``runtime.execution_graph()`` produces a ``StepBuilder`` / ``OperationCollection``, you can read each operation's :class:`OperationMetadata` and feed it to :func:`dependency_dag`. Open ``dag.html`` in a browser. Nodes carry the ``op_name``, ``operation_number``, and ``shape`` / ``color`` hints from the metadata; edges follow the resolved ``depends_on`` / ``before`` relationships. .. GENERATED FROM PYTHON SOURCE LINES 21-45 .. code-block:: Python from typing import Any import matplotlib.pyplot as plt import networkx as nx from neofoam.framework.graph import ( build_dependency_digraph, dependency_dag, digraph_to_pyvis_html, validate_dependency_graph, ) def render_solver_dag(runtime: Any, out: str = "dag.html") -> None: builder, model_ops = runtime.execution_graph() metas_by_domain = { "main": [op.metadata for op in builder.operations.ops] + [op.metadata for op in model_ops.ops], } graph = dependency_dag(metas_by_domain) digraph_to_pyvis_html(graph, out) .. GENERATED FROM PYTHON SOURCE LINES 46-53 A worked example ---------------- Build a small PISO-style dependency graph and render it two ways: inline as a static figure (so it appears below this cell on the docs page), and as an interactive ``dag.html`` you can open in a browser to drag nodes and inspect edges. The same :class:`networkx.DiGraph` feeds both renderers. .. GENERATED FROM PYTHON SOURCE LINES 53-88 .. code-block:: Python graph = build_dependency_digraph( { "U_predictor": [], "p_corrector": ["U_predictor"], "U_corrector": ["p_corrector"], "write_output": ["U_corrector"], } ) fig, ax = plt.subplots(figsize=(7, 3.5)) layout = { "U_predictor": (0, 0), "p_corrector": (1, 0), "U_corrector": (2, 0), "write_output": (3, 0), } nx.draw( graph, pos=layout, ax=ax, with_labels=True, node_color="lightblue", node_size=2400, edgecolors="black", font_size=9, arrowsize=18, ) ax.set_title("PISO-style operation DAG") fig.tight_layout() # Same graph, written to an interactive pyvis page. digraph_to_pyvis_html(graph, "dag.html") .. image-sg:: /auto_how-to/images/sphx_glr_example_visualize_the_operation_dag_001.png :alt: PISO-style operation DAG :srcset: /auto_how-to/images/sphx_glr_example_visualize_the_operation_dag_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 89-95 Inspect without rendering ------------------------- The intermediate :class:`networkx.DiGraph` is plain ``networkx`` — you can call ``graph.predecessors(name)``, ``graph.successors(name)``, or ``nx.find_cycle(graph)`` directly. Useful inside tests or while debugging. .. GENERATED FROM PYTHON SOURCE LINES 95-100 .. code-block:: Python assert list(graph.successors("U_predictor")) == ["p_corrector"] print("successors of U_predictor:", list(graph.successors("U_predictor"))) .. rst-class:: sphx-glr-script-out .. code-block:: none successors of U_predictor: ['p_corrector'] .. GENERATED FROM PYTHON SOURCE LINES 101-107 Validate before you resolve --------------------------- If you only want to know *whether* a graph is well-formed (no duplicates, no missing dependencies, no cycles) use :func:`validate_dependency_graph` — it returns a :class:`GraphValidationReport` you can inspect without raising. .. GENERATED FROM PYTHON SOURCE LINES 107-117 .. code-block:: Python report = validate_dependency_graph( node_names=["A", "B", "C"], dependencies_by_node={"A": [], "B": ["A"], "C": ["B", "missing"]}, ) if not report.is_valid: for diagnostic in report.diagnostics: print(diagnostic.code, diagnostic.message) .. rst-class:: sphx-glr-script-out .. code-block:: none missing_dependency InitStep 'C' depends on 'missing', but 'missing' was not found .. GENERATED FROM PYTHON SOURCE LINES 118-124 See also -------- - :doc:`/explanation/operations-and-the-dag` — design rationale and the resolver pipeline. - :doc:`/reference/graph/visualization` — full API. .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.080 seconds) .. _sphx_glr_download_auto_how-to_example_visualize_the_operation_dag.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: example_visualize_the_operation_dag.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: example_visualize_the_operation_dag.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: example_visualize_the_operation_dag.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_