(
expr: BaseExpr, stage: OptimizerStage = "fused", format: str | None = None
)
| 18 | |
| 19 | |
| 20 | def explain( |
| 21 | expr: BaseExpr, stage: OptimizerStage = "fused", format: str | None = None |
| 22 | ) -> None: |
| 23 | graphviz = import_required( |
| 24 | "graphviz", "graphviz is a required dependency for using the explain method." |
| 25 | ) |
| 26 | |
| 27 | if format is None: |
| 28 | format = "png" |
| 29 | |
| 30 | g = graphviz.Digraph( |
| 31 | STAGE_LABELS[stage], filename=f"explain-{stage}-{expr._name}", format=format |
| 32 | ) |
| 33 | g.node_attr.update(shape="record") |
| 34 | |
| 35 | expr = optimize_until(expr, stage) |
| 36 | |
| 37 | seen = set(expr._name) |
| 38 | stack: list[BaseExpr] = [expr] |
| 39 | |
| 40 | while stack: |
| 41 | node = stack.pop() |
| 42 | explain_info = _explain_info(node) |
| 43 | _add_graphviz_node(explain_info, g) |
| 44 | _add_graphviz_edges(explain_info, g) |
| 45 | |
| 46 | for dep in node.operands: |
| 47 | if not isinstance(dep, Expr) or dep._name in seen: |
| 48 | continue |
| 49 | seen.add(dep._name) |
| 50 | stack.append(dep) |
| 51 | |
| 52 | g.view() |
| 53 | |
| 54 | |
| 55 | def _add_graphviz_node(explain_info, graph): |
no test coverage detected
searching dependent graphs…