docstr: Make sure that all permutable nodes/parameters were actually permuted and all GPUs agree
code: def check_graph_for_unpermuted_nodes(cls, fx_graph):
      """Make sure that all permutable nodes/parameters were actually permuted and all GPUs agree"""
  
      for node_name in fx_graph.keys():
          node = fx_graph[node_name]
  
          if (
              "C_permutable" in node.keys()
              and node["C_permutable"]
              and not node["C_permuted"]
          ):
              sibling_group_id = node["sibling_group_id"]
              if (
                  node["is_real"]
                  and cls.__group_data["skipped_sibling_groups"][
                      sibling_group_id
                  ]
                  is None
              ):
                  if cls.__verbosity >= 0:
                      print(
                          f"{node_name} was C_permutable in a not skipped sibling group but was not permuted along C! {node}"
                      )
                  cls.__unpermuted_dims.append(node_name + "_C")
  
          if (
              "K_permutable" in node.keys()
              and node["K_permutable"]
              and not node["K_permuted"]
          ):
              coparent_group_id = node["coparent_group_id"]
              if (
                  node["is_real"]
                  and cls.__group_data["skipped_coparent_groups"][
                      coparent_group_id
                  ]
                  is None
              ):
                  if cls.__verbosity >= 0:
                      print(
                          f"{node_name} was K_permutable in a not skipped coparent group but was not permuted along K! {node}"
                      )
                  cls.__unpermuted_dims.append(node_name + "_K")
  
      if cls.__verbosity > 0:
          print(
              f"[check_graph_for_unpermuted_nodes] found nodes that missed permutations along {len(cls.__unpermuted_dims)} dimensions."
          )
  
      # make sure all GPUs agree
      if torch.distributed.is_initialized():
          cls.__unpermuted_dims = sorted(cls.__unpermuted_dims)
          rank = torch.distributed.get_rank()
          world_size = torch.distributed.get_world_size()
          dist_store = torch.distributed.TCPStore(
              "127.0.0.1", cls.__tcpstore_port, world_size, rank == 0
          )
          torch.distributed.barrier()
  
          dist_store.set(str(rank), ",".join(cls.__unpermuted_dims))
          torch.distributed.barrier()
  
          if rank == 0:
              my_list = dist_store.get("0").decode()
  
              for peer in range(1, world_size):
                  peer_list = dist_store.get(str(peer)).decode()
                  assert (
                      my_list == peer_list
                  ), f"peer {peer} disagreed with rank 0's list of unpermuted nodes: \n{my_list}\n{peer_list}"
  
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 11 for calling the Permutation obj's underlying member method code with example usage: obj.check_graph_for_unpermuted_nodes(cls, fx_graph) without return types