code: def get_numa_nodes_cores() -> Dict[str, Any]:
      """Parses numa nodes information into a dictionary.
  
      ..code-block::
  
          {<node_id>: [(<core_id>, [<sibling_thread_id_0>, <sibling_thread_id_1>
          ...]), ...], ...}
  
          # For example:
          {0: [(0, [0, 4]), (1, [1, 5])], 1: [(2, [2, 6]), (3, [3, 7])]}
  
      If not available, returns an empty dictionary.
      """
      numa_node_paths = glob.glob("/sys/devices/system/node/node[0-9]*")
  
      if not numa_node_paths:
          return {}
  
      nodes = {}
      try:
          for node_path in numa_node_paths:
              numa_node_id = int(osp.basename(node_path)[4:])
  
              thread_siblings = {}
              for cpu_dir in glob.glob(
                  osp.join(node_path, "cpu[0-9]*")
              ):
                  cpu_id = int(osp.basename(cpu_dir)[3:])
                  if cpu_id > 0:
                      with open(
                          osp.join(cpu_dir, "online")
                      ) as core_online_file:
                          core_online = int(
                              core_online_file.read().splitlines()[0]
                          )
                  else:
                      core_online = (
                          1  # cpu0 is always online (special case)
                      )
                  if core_online == 1:
                      with open(
                          osp.join(cpu_dir, "topology", "core_id")
                      ) as core_id_file:
                          core_id = int(core_id_file.read().strip())
                          if core_id in thread_siblings:
                              thread_siblings[core_id].append(cpu_id)
                          else:
                              thread_siblings[core_id] = [cpu_id]
  
              nodes[numa_node_id] = sorted(
                  [(k, sorted(v)) for k, v in thread_siblings.items()]
              )
  
      except (OSError, ValueError, IndexError, IOError):
          Warning("Failed to read NUMA info")
          return {}
  
      return nodes
  
imports: import glob
  import logging
  import os
  import os.path
  import warnings
  from contextlib import contextmanager
  from typing import Any, Callable, Dict, List, Optional, Union
  import psutil
  import torch
  from torch_geometric.data import HeteroData
label_desc: Use image node_id 1 for calling a global function with example usage: get_numa_nodes_cores() and returns: nodes, dict, dict