code: def forward_backward_no_pipelining(
      *,
      forward_step_func,
      data_iterator: Union[Iterator, List[Iterator]],
      model: Union[torch.nn.Module, List[torch.nn.Module]],
      num_microbatches: int,
      seq_length: int,  # unused
      micro_batch_size: int,  # unused
      decoder_seq_length: int = None,  # unused
      forward_only: bool = False,
      collect_non_loss_data: bool = False,
  ):
      """Run forward and backward passes with no pipeline parallelism
      (no inter-stage communication).
  
      Returns dictionary with losses.
  
  
      See get_forward_backward_func() for argument details
      """
  
      if isinstance(model, list):
          assert (
              len(model) == 1
          ), "non-pipeline-parallel schedule does not support model chunking"
          model = model[0]
      if isinstance(data_iterator, list):
          assert (
              len(data_iterator) == 1
          ), "non-pipeline-parallel schedule does not support model chunking"
          data_iterator = data_iterator[0]
  
      config = get_model_config(model)
      if config.timers is not None:
          config.timers("forward-backward", log_level=1).start(
              barrier=config.barrier_with_L1_time
          )
  
      no_sync_func = config.no_sync_func
      if no_sync_func is None:
          no_sync_func = contextlib.nullcontext
  
      model_type = get_model_type(model)
  
      forward_data_store = []
      input_tensor, output_tensor_grad = None, None
      with no_sync_func():
          for i in range(num_microbatches - 1):
              output_tensor = forward_step(
                  forward_step_func,
                  data_iterator,
                  model,
                  num_microbatches,
                  input_tensor,
                  forward_data_store,
                  config,
                  collect_non_loss_data,
              )
              if not forward_only:
                  backward_step(
                      input_tensor,
                      output_tensor,
                      output_tensor_grad,
                      model_type,
                      config,
                  )
  
      # Run computation for last microbatch out of context handler (want to
      # synchronize gradients).
      output_tensor = forward_step(
          forward_step_func,
          data_iterator,
          model,
          num_microbatches,
          input_tensor,
          forward_data_store,
          config,
          collect_non_loss_data,
      )
  
      if not forward_only:
          backward_step(
              input_tensor,
              output_tensor,
              output_tensor_grad,
              model_type,
              config,
          )
  
      if config.timers is not None:
          config.timers("forward-backward").stop()
  
      if (
          config.finalize_model_grads_func is not None
          and not forward_only
      ):
          # Finalize model grads (perform full grad all-reduce / reduce-scatter for
          # data parallelism and layernorm all-reduce for sequence parallelism).
          config.finalize_model_grads_func([model])
  
      return forward_data_store
  
imports: import contextlib
  from typing import Callable, Iterator, List, Optional, Union
  import torch
  from torch.autograd.variable import Variable
  from megatron.core import parallel_state
  from megatron.core.enums import ModelType
  from megatron.core.pipeline_parallel import p2p_communication
  from megatron.core.utils import get_attr_wrapped_model, get_model_config, get_model_type
label_desc: Use image node_id 6 for calling a global function with example usage: forward_backward_no_pipelining() and returns: forward_data_store