code: def _init_inter_node_process_group(
      global_process_group: dist.ProcessGroup,
      num_devices_per_node: int,
  ) -> dist.ProcessGroup:
      """
      Return an inter-node process group where each contained rank has the same local rank.
  
      For example, given each row is a distinct node:
      0 1 2 3 4 5 6 7 8
      9 10 11 12 13 14 15
      This API would return inter-node process group {0, 8}, {1, 9}, {2, 10}, and so forth
      depending on the process's rank. For example, rank 1 would get {1, 9}, rank 5
      would get {5, 13}.
      """
      # the inter-node pg that is returned
      inter_node_pg = None
      sharding_backend = dist.get_backend(global_process_group)
      world_size = dist.get_world_size(global_process_group)
      # Assuming fully homogeneous setup
      num_nodes = world_size // num_devices_per_node
      my_local_rank = (
          dist.get_rank(global_process_group) % num_devices_per_node
      )
      for local_rank in range(num_devices_per_node):
          ranks_for_inter_group = [
              local_rank + (i * num_devices_per_node)
              for i in range(num_nodes)
          ]
          # every rank always needs to call dist.new_group
          grp = dist.new_group(
              ranks=ranks_for_inter_group, backend=sharding_backend
          )
          if local_rank == my_local_rank:
              inter_node_pg = grp
  
      assert (
          inter_node_pg is not None
      ), f"{my_local_rank} expected to assign inter-node pg, but did not"
      return inter_node_pg
  
imports: import collections
  import itertools
  import os
  import warnings
  from typing import Any, Callable, Deque, Dict, Generator, Iterable, Iterator, List, no_type_check, Optional, Set, Tuple, Union
  import torch
  import torch.distributed
  import torch.distributed.fsdp._exec_order_utils
  import torch.distributed.fsdp._traversal_utils
  import torch.distributed.fsdp.fully_sharded_data_parallel
  import torch.nn
  from torch.distributed.algorithms._comm_hooks import default_hooks
  from torch.distributed.device_mesh import _mesh_resources, DeviceMesh
  from torch.distributed.distributed_c10d import _get_default_group
  from torch.distributed.fsdp._common_utils import _FSDPDeviceHandle, _FSDPState, _get_module_fsdp_state, _is_fsdp_flattened, _named_parameters_with_duplicates, clean_tensor_name, TrainingState
  from torch.distributed.fsdp._flat_param import _FSDP_USE_FULL_PREC_IN_EVAL, FlatParameter, FlatParamHandle, HandleShardingStrategy
  from torch.distributed.fsdp._limiter_utils import _FreeEventQueue
  from torch.distributed.fsdp.api import BackwardPrefetch, CPUOffload, FullOptimStateDictConfig, FullStateDictConfig, MixedPrecision, ShardingStrategy, StateDictConfig, StateDictType
  from torch.distributed.fsdp.wrap import _Policy
  from torch.distributed.tensor.parallel.fsdp import DTensorExtensions
  from torch.distributed.utils import _sync_params_and_buffers
  from torch.utils._python_dispatch import is_traceable_wrapper_subclass
  from torch.utils.hooks import RemovableHandle
label_desc: Use image node_id 6 for calling a global function with example usage: _init_inter_node_process_group(global_process_group, num_devices_per_node) and returns: inter_node_pg