code: def test_transfer_batch_hook_ddp(tmpdir):
      """Test custom data are properly moved to the right device using ddp."""
  
      class CustomBatch:
          def __init__(self, data):
              self.samples = data[0]
  
          def to(self, device, **kwargs):
              self.samples = self.samples.to(device, **kwargs)
              return self
  
      def collate_fn(batch):
          return CustomBatch(batch)
  
      class TestModel(BoringModel):
          def training_step(self, batch, batch_idx):
              assert batch.samples.device == self.device
              assert isinstance(batch_idx, int)
  
          def train_dataloader(self):
              return torch.utils.data.DataLoader(
                  RandomDataset(32, 64), collate_fn=collate_fn
              )
  
      model = TestModel()
      model.validation_step = None
      trainer = Trainer(
          default_root_dir=tmpdir,
          limit_train_batches=2,
          limit_val_batches=0,
          max_epochs=1,
          strategy="ddp",
          accelerator="gpu",
          devices=2,
          enable_progress_bar=False,
          enable_model_summary=False,
      )
      trainer.fit(model)
  
imports: from functools import partial, update_wrapper
  from inspect import getmembers, isfunction
  from unittest import mock
  from unittest.mock import ANY, PropertyMock
  import pytest
  import torch
  from lightning.fabric.utilities.imports import _TORCH_GREATER_EQUAL_2_0
  from lightning.pytorch import Callback, LightningDataModule, LightningModule, Trainer, __version__
  from lightning.pytorch.demos.boring_classes import BoringDataModule, BoringModel, RandomDataset
  from lightning.pytorch.utilities.model_helpers import is_overridden
  from torch import Tensor
  from torch.utils.data import DataLoader
  from tests_pytorch.helpers.runif import RunIf
label_desc: Use image node_id 4 for calling a global function with example usage: test_transfer_batch_hook_ddp(tmpdir) and returns: CustomBatch, self, torch