numa.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import os
  2. import useful
  3. #
  4. def check_path_traversal(path, base_path):
  5. # this is not guarenteed to be secure
  6. if os.path.commonprefix([os.path.realpath(path), base_path]) != base_path:
  7. raise Exception('The path \'{}\' is not in the base path \'{}.\''.format(os.path.realpath(path), base_path))
  8. #
  9. #
  10. def get_online_numa_nodes():
  11. with open('/sys/devices/system/node/online', 'r') as f:
  12. online_nodes = f.read().strip()
  13. return useful.parse_range_list(online_nodes)
  14. #
  15. #
  16. def get_processors_in_numa_node(node_id):
  17. path = '/sys/devices/system/node/node{}/cpulist'.format(node_id)
  18. check_path_traversal(path, '/sys/devices/system/node')
  19. with open(path, 'r') as f:
  20. return useful.parse_range_list(f.read().strip())
  21. #
  22. #
  23. def get_thread_siblings(processor_id):
  24. path = '/sys/devices/system/cpu/cpu{}/topology/thread_siblings_list'.format(processor_id)
  25. check_path_traversal(path, '/sys/devices/system/cpu')
  26. with open(path, 'r') as f:
  27. return useful.parse_range_list(f.read().strip())
  28. #
  29. #
  30. def get_numa_overview():
  31. numa_nodes = {}
  32. #
  33. for node_id in get_online_numa_nodes():
  34. numa_nodes[node_id] = {}
  35. #
  36. for node_id in numa_nodes:
  37. processors = get_processors_in_numa_node(node_id)
  38. #
  39. numa_nodes[node_id]['physical_cores'] = []
  40. for processor_id in processors:
  41. thread_siblings = sorted(get_thread_siblings(processor_id))
  42. #
  43. if thread_siblings not in numa_nodes[node_id]['physical_cores']:
  44. numa_nodes[node_id]['physical_cores'].append(thread_siblings)
  45. #
  46. #
  47. #
  48. return numa_nodes
  49. #
  50. if __name__ == '__main__':
  51. print(get_numa_overview())
  52. #