docstr: Traverse all real nodes in the graph and collect their siblings and coparents
code: def make_sibling_coparent_groups(cls, fx_graph):
      """Traverse all real nodes in the graph and collect their siblings and coparents"""
  
      if cls.__verbosity > 0:
          print("[make_sibling_coparent_groups]")
  
      for node_name in fx_graph.keys():
          fx_node = fx_graph[node_name]
  
          if "is_real" in fx_node.keys() and fx_node["is_real"]:
              sibling_group_id = fx_node["sibling_group_id"]
              if (
                  sibling_group_id is None
              ):  # need to make a new sibling group for this node
                  all_siblings = cls.collect_siblings(
                      fx_graph, node_name, set([node_name])
                  )
                  all_siblings = sorted(
                      all_siblings
                  )  # deterministic order for DDP setups
                  sibling_group_id = cls.__group_data[
                      "next_sibling_group_id"
                  ]
                  cls.__group_data["sibling_groups"][
                      sibling_group_id
                  ] = all_siblings
                  cls.__group_data["next_sibling_group_id"] = (
                      sibling_group_id + 1
                  )
  
                  sibling_group_C_params = []
                  for sibling in all_siblings:
                      fx_graph[sibling][
                          "sibling_group_id"
                      ] = sibling_group_id
                      sibling_C_param = int(
                          fx_graph[sibling]["C_param"]
                      )
                      sibling_group_C_params.append(sibling_C_param)
  
                  # if grouped convolutions make the input channels different among siblings different sizes,
                  # restrict the permutation atom to the greatest common divisor so it can be tiled as needed for each sibling (and parent)
                  sibling_group_C_param = str(
                      np.gcd.reduce(sibling_group_C_params)
                  )
                  cls.__group_data["sibling_group_C_params"][
                      sibling_group_id
                  ] = sibling_group_C_param
                  cls.__group_data["skipped_sibling_groups"][
                      sibling_group_id
                  ] = None
  
                  if cls.__verbosity > 1:
                      print(
                          f"New sibling group {sibling_group_id} with GCD(C) of {sibling_group_C_param}: {all_siblings}"
                      )
  
              coparent_group_id = fx_node["coparent_group_id"]
              if coparent_group_id is None:
                  all_coparents = cls.collect_coparents(
                      fx_graph, node_name, set([node_name])
                  )
                  coparent_group_id = cls.__group_data[
                      "next_coparent_group_id"
                  ]
                  cls.__group_data["coparent_groups"][
                      coparent_group_id
                  ] = all_coparents
                  cls.__group_data["next_coparent_group_id"] = (
                      coparent_group_id + 1
                  )
                  cls.__group_data["skipped_coparent_groups"][
                      coparent_group_id
                  ] = None
  
                  for coparent in all_coparents:
                      fx_graph[coparent][
                          "coparent_group_id"
                      ] = coparent_group_id
  
                  if cls.__verbosity > 1:
                      print(
                          f"New coparent group {coparent_group_id}: {all_coparents}"
                      )
      return fx_graph
  
imports: import os
  import torch
  import json
  import string
  import time
  import numpy
  import sys
  import builtins
  import io
label_desc: Use image node_id 33 for calling the Permutation obj's underlying member method code with example usage: obj.make_sibling_coparent_groups(cls, fx_graph) and returns: fx_graph