code: def fastnlp_torch_gather_object(
      obj, dst=0, group=DEFAULT_TORCH_GROUP
  ):
      """
      从其它 rank gather 东西到 dst rank 。
  
      Example::
          >>> # Assumes world_size of 3.
          >>> gather_objects = ["foo", 12, {1: 2}] # any picklable object
          >>> output = [None for _ in gather_objects]
          >>> fastnlp_torch_gather_object(
                  gather_objects[dist.get_rank()],
                  output if dist.get_rank() == 0 else None,
                  dst=0
              )
          >>> # On rank 0
          >>> output
          ['foo', 12, {1: 2}]
  
      :param obj: 需要发送的 obj 对象，需要是可以 pickable 的对象
      :param dst: 目标的 rank 。
      :param group: 在哪个 group 执行该函数。
      :return: 在 dst 上面返回 world_size 的 list，依次为 rank 0；rank 1...上 obj
      """
      if int(os.environ.get(FASTNLP_NO_SYNC, "0")) == 2:
          return [obj]
  
      if dist.get_rank() == dst:
          object_gather_list = [
              None for _ in range(dist.get_world_size(group))
          ]
      else:
          object_gather_list = None
  
      if group is None:
          group = DEFAULT_TORCH_GROUP
  
      if dist.distributed_c10d._rank_not_in_group(group):
          return
  
      # Ensure object_gather_list is specified appopriately.
      my_rank = dist.get_rank()
      _validate_output_list_for_rank(my_rank, dst, object_gather_list)
      # 防止 unpickle 的时候出现在了发送的 gpu 上。
      obj = apply_to_collection(
          obj, torch.Tensor, _to_device, device=torch.device("cpu")
      )
      input_tensor, local_size = _object_to_tensor(obj)
      group_backend = dist.get_backend(group)
      current_device = torch.device("cpu")
      is_nccl_backend = group_backend == dist.Backend.NCCL
      if is_nccl_backend:
          current_device = torch.device(
              "cuda", torch.cuda.current_device()
          )
          input_tensor = input_tensor.to(current_device)
          local_size = local_size.to(current_device)
      # Gather all local sizes. This is so that we can find the max size, and index
      # until the correct size when deserializing the tensors.
      group_size = dist.get_world_size(group=group)
      object_sizes_tensor = torch.zeros(
          group_size, dtype=torch.long, device=current_device
      )
      object_size_list = [
          object_sizes_tensor[i].unsqueeze(dim=0)
          for i in range(group_size)
      ]
      # Allgather tensor sizes. An all-gather is needed here despite this being a
      # gather, since each rank needs to broadcast a tensor of the same (maximal)
      # size.
      dist.all_gather(object_size_list, local_size, group=group)
      max_object_size = int(max(object_size_list).item())  # type: ignore[type-var]
      # Resize tensor to max size across all ranks.
      input_tensor.resize_(max_object_size)
      # Avoid populating output tensors if the result won't be gathered on this rank.
      if my_rank == dst:
          coalesced_output_tensor = torch.empty(
              max_object_size * group_size,
              dtype=torch.uint8,
              device=current_device,
          )
          # Output tensors are nonoverlapping views of coalesced_output_tensor
          output_tensors = [
              coalesced_output_tensor[
                  max_object_size * i : max_object_size * (i + 1)
              ]
              for i in range(group_size)
          ]
      # All ranks call gather with equal-sized tensors.
      dist.gather(
          input_tensor,
          gather_list=output_tensors if my_rank == dst else None,
          dst=dst,
          group=group,
      )
      if my_rank != dst:
          return
      for i, tensor in enumerate(output_tensors):
          tensor = tensor.type(torch.uint8)  # type: ignore[call-overload]
          tensor_size = object_size_list[i]
          object_gather_list[i] = _tensor_to_object(tensor, tensor_size)
  
file_path: fastNLP/fastNLP/core/drivers/torch_driver/dist_utils.py
imports: import io
  import pickle
  import os
  from typing import Any, List
  from fastNLP.envs.imports import _TORCH_GREATER_EQUAL_1_8
  from fastNLP.core.utils.torch_utils import DEFAULT_TORCH_GROUP
  from fastNLP.envs.imports import _NEED_IMPORT_TORCH
  from fastNLP.envs.env import FASTNLP_NO_SYNC
  from fastNLP.core.utils import apply_to_collection
label_desc: Use image node_id 2 for calling a global function with example usage: fastnlp_torch_gather_object(obj, dst, group) and returns: list