class_docstr: A derivative of `fx.GraphModule`. Differs in the following ways:
  - Requires a train and eval version of the underlying graph
  - Copies submodules according to the nodes of both train and eval graphs.
  - Calling train(mode) switches between train graph and eval graph.
docstr: Args:
      root (nn.Module): module from which the copied module hierarchy is
          built
      train_graph (fx.Graph): the graph that should be used in train mode
      eval_graph (fx.Graph): the graph that should be used in eval mode
docstr_tok: ["Args",":","root","(","nn.Module",")",":","module","from","which","the","copied","module","hierarchy","is","built","train_graph","(","fx.Graph",")",":","the","graph","that","should","be","used","in","train","mode","eval_graph","(","fx.Graph",")",":","the","graph","that","should","be","used","in","eval","mode"]
code: def __init__(
      self,
      root: torch.nn.Module,
      train_graph: fx.Graph,
      eval_graph: fx.Graph,
      class_name: str = "GraphModule",
  ):
      """
      Args:
          root (nn.Module): module from which the copied module hierarchy is
              built
          train_graph (fx.Graph): the graph that should be used in train mode
          eval_graph (fx.Graph): the graph that should be used in eval mode
      """
      super(fx.GraphModule, self).__init__()
  
      self.__class__.__name__ = class_name
  
      self.train_graph = train_graph
      self.eval_graph = eval_graph
  
      # Copy all get_attr and call_module ops (indicated by BOTH train and
      # eval graphs)
      for node in chain(
          iter(train_graph.nodes), iter(eval_graph.nodes)
      ):
          if node.op in ["get_attr", "call_module"]:
              if not isinstance(node.target, str):
                  raise TypeError(
                      f"node.target should be of type str instead of {type(node.target)}"
                  )
              _copy_attr(root, self, node.target)
  
      # train mode by default
      self.train()
      self.graph = train_graph
  
      # (borrowed from fx.GraphModule):
      # Store the Tracer class responsible for creating a Graph separately as part of the
      # GraphModule state, except when the Tracer is defined in a local namespace.
      # Locally defined Tracers are not pickleable. This is needed because torch.package will
      # serialize a GraphModule without retaining the Graph, and needs to use the correct Tracer
      # to re-create the Graph during deserialization.
      if self.eval_graph._tracer_cls != self.train_graph._tracer_cls:
          raise TypeError(
              f"Train mode and eval mode should use the same tracer class. Instead got {self.eval_graph._tracer_cls} for eval vs {self.train_graph._tracer_cls} for train"
          )
      self._tracer_cls = None
      if (
          self.graph._tracer_cls
          and "<locals>" not in self.graph._tracer_cls.__qualname__
      ):
          self._tracer_cls = self.graph._tracer_cls
  
imports: import inspect
  import math
  import re
  import warnings
  from collections import OrderedDict
  from copy import deepcopy
  from itertools import chain
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
  import torch
  import torchvision
  from torch import fx, nn
  from torch.fx.graph_module import _copy_attr
label_desc: Use image node_id 1 to create a new DualGraphModule object from inherited base classes: fx with example: obj = DualGraphModule(root, train_graph, eval_graph, class_name)