code: def train_fabric(fabric):
      make_deterministic(warn_only=True)
      memory_stats = {}
  
      model = ConvNet()
      initial_state_dict = deepcopy(model.state_dict())
  
      optimizer = model.get_optimizer()
      model, optimizer = fabric.setup(model, optimizer)
  
      dataloader = model.get_dataloader()
      dataloader = fabric.setup_dataloaders(dataloader)
      loss_fn = model.get_loss_function()
  
      memory_stats["start"] = torch.cuda.memory_stats()
  
      model.train()
      iteration_timings = []
      iterator = iter(dataloader)
      for _ in range(model.num_steps):
          t0 = time.perf_counter()
  
          inputs, labels = next(iterator)
          optimizer.zero_grad()
          outputs = model(inputs)
          loss = loss_fn(outputs, labels)
          fabric.backward(loss)
          optimizer.step()
  
          t1 = time.perf_counter()
          iteration_timings.append(t1 - t0)
  
      memory_stats["end"] = torch.cuda.memory_stats()
  
      # check that the model has changed
      assert not is_state_dict_equal(
          initial_state_dict, model.state_dict()
      )
  
      return (
          model.state_dict(),
          torch.tensor(iteration_timings),
          memory_stats,
      )
  
file_path: pytorch-lightning/tests/parity_fabric/test_parity_simple.py
imports: import time
  from copy import deepcopy
  from typing import Callable
  import pytest
  import torch
  import torch.distributed
  import torch.nn.functional
  from lightning.fabric.fabric import Fabric
  from tests_fabric.helpers.runif import RunIf
  from parity_fabric.models import ConvNet
  from parity_fabric.utils import cuda_reset, get_model_input_dtype, is_cuda_memory_close, is_state_dict_equal, is_timing_close, make_deterministic
label_desc: Use image node_id 2 for calling a global function with example usage: train_fabric(fabric) and returns: model,  torch,  memory_stats