code: def _generate_module_summary(
      module: torch.nn.Module,
      module_name: str,
      module_summary_data: _ModuleSummaryData,
  ) -> ModuleSummary:
      """
      Recursively generate and populate metrics for ModelSummary.
      """
      module_summary = ModuleSummary()
      module_summary._module_name = module_name
      module_summary._module_type = str(module.__class__.__name__)
  
      for name, submodule in module.named_children():
          formatted_name = (
              f"{module_name}.{name}" if module_name != "" else name
          )
  
          submodule_summary = _generate_module_summary(
              submodule, formatted_name, module_summary_data
          )
  
          # Add results from submodule summary
          module_summary._submodule_summaries[
              formatted_name
          ] = submodule_summary
          module_summary._has_uninitialized_param = (
              module_summary._has_uninitialized_param
              or submodule_summary._has_uninitialized_param
          )
          module_summary._num_parameters += (
              submodule_summary._num_parameters
          )
          module_summary._num_trainable_parameters += (
              submodule_summary._num_trainable_parameters
          )
          module_summary._size_bytes += submodule_summary._size_bytes
  
      for param in module.parameters(recurse=False):
          if isinstance(param, UninitializedParameter):
              module_summary._has_uninitialized_param = True
          else:
              numel = param.numel()
              module_summary._num_parameters += numel
              module_summary._size_bytes += numel * param.element_size()
              if param.requires_grad:
                  module_summary._num_trainable_parameters += numel
  
      for buf in module.buffers(recurse=False):
          module_summary._size_bytes += buf.numel() * buf.element_size()
  
      flops_forward = module_summary_data.flops_forward
      flops_backward = module_summary_data.flops_backward
      activation_sizes = module_summary_data.activation_sizes
      forward_elapsed_times_ms = (
          module_summary_data.forward_elapsed_times_ms
      )
  
      # Calculate flops forward/backward.
      if flops_forward is not None:
          module_summary._flops_forward_detail = dict(
              flops_forward[module_name]
          )
          module_summary._flops_forward = sum(
              [v for k, v in flops_forward[module_name].items()]
          )
      if flops_backward is not None:
          module_summary._flops_backward_detail = dict(
              flops_backward[module_name]
          )
          module_summary._flops_backward = sum(
              [v for k, v in flops_backward[module_name].items()]
          )
  
      # set activation sizes
      if module_name in activation_sizes:
          in_size, out_size = activation_sizes[module_name]
          module_summary._in_size = in_size
          module_summary._out_size = out_size
  
      # set forward elasped times
      if module_name in forward_elapsed_times_ms:
          module_summary._forward_time_elapsed_ms = (
              forward_elapsed_times_ms[module_name]
          )
  
      return module_summary
  
imports: import copy
  import math
  import warnings
  from collections import defaultdict, deque
  from dataclasses import dataclass, field
  from enum import Enum
  from time import perf_counter
  from typing import Any, Callable, DefaultDict, Deque, Dict, List, MutableMapping, Optional, Tuple, Union
  import torch
  from torch.nn.parameter import UninitializedParameter
  from torch.utils._pytree import PyTree, tree_flatten
  from torch.utils.hooks import RemovableHandle
  from torchtnt.utils.version import is_torch_version_geq_1_13
  from typing_extensions import Literal
label_desc: Use image node_id 6 for calling a global function with example usage: _generate_module_summary(module, module_name, module_summary_data) and returns: module_summary