class_docstr: DOT language graph plotter
  
  The plotter accepts various graphviz attributes for graphs, nodes, and edges.
  Please refer to https://graphviz.org/doc/info/attrs.html for available attributes.
  
  Parameters
  ----------
  graph_attr: Optional[Dict[str, str]]
      key-value pairs for all graphs.
  node_attr: Optional[Dict[str, str]]
      key-value pairs for all nodes.
  edge_attr: Optional[Dict[str, str]]
      key-value pairs for all edges.
  get_node_attr: Optional[Callable[[VizNode], Dict[str, str]]]
      A callable returning attributes for a specific node.
  render_kwargs: Optional[Dict[str, Any]]
      keyword arguments directly passed to `graphviz.Digraph.render()`.
  
  Examples
  --------
  
  .. code-block:: python
  
      from tvm.contrib import relay_viz
      from tvm.relay.testing import resnet
  
      mod, param = resnet.get_workload(num_layers=18)
      # graphviz attributes
      graph_attr = {"color": "red"}
      node_attr = {"color": "blue"}
      edge_attr = {"color": "black"}
  
      # VizNode is passed to the callback.
      # We want to color NCHW conv2d nodes. Also give Var a different shape.
      def get_node_attr(node):
          if "nn.conv2d" in node.type_name and "NCHW" in node.detail:
              return {
                  "fillcolor": "green",
                  "style": "filled",
                  "shape": "box",
              }
          if "Var" in node.type_name:
              return {"shape": "ellipse"}
          return {"shape": "box"}
  
      # Create plotter and pass it to viz. Then render the graph.
      dot_plotter = relay_viz.DotPlotter(
          graph_attr=graph_attr,
          node_attr=node_attr,
          edge_attr=edge_attr,
          get_node_attr=get_node_attr)
  
      viz = relay_viz.RelayVisualizer(
          mod,
          relay_param=param,
          plotter=dot_plotter,
          parser=relay_viz.DotVizParser())
      viz.render("hello")
docstr: render the graph generated from the Relay IR module.
  
  This function is a thin wrapper of `graphviz.Digraph.render()`.
docstr_tok: ["render","the","graph","generated","from","the","Relay","IR","module",".","This","function","is","a","thin","wrapper","of","`","graphviz.Digraph.render","(",")","`","."]
code: def render(self, filename: str = None):
      """render the graph generated from the Relay IR module.
  
      This function is a thin wrapper of `graphviz.Digraph.render()`.
      """
      # Create or update the filename
      if filename is not None:
          self._render_kwargs["filename"] = filename
      # default cleanup
      if "cleanup" not in self._render_kwargs:
          self._render_kwargs["cleanup"] = True
  
      root_graph = graphviz.Digraph()
      for graph in self._name_to_graph.values():
          root_graph.subgraph(graph.digraph)
      root_graph.render(**self._render_kwargs)
  
file_path: tvm/python/tvm/contrib/relay_viz/dot.py
imports: from typing import Any, Callable, Dict
  from .interface import DefaultVizParser, Plotter, VizEdge, VizGraph, VizNode
label_desc: Use image node_id 3 for calling the DotPlotter obj's underlying member method code with example usage: obj.render(filename) without return types