rteval/rteval-Create-common-functi...

214 lines
7.3 KiB
Diff

From f1c540ea023bbbcd901e6b6d27d993851eae0e9b Mon Sep 17 00:00:00 2001
From: John Kacur <jkacur@redhat.com>
Date: Mon, 25 Jul 2022 11:14:41 -0400
Subject: [PATCH 03/19] rteval: Create common functions in CpuList and
SysTopology
The purpose is to remove functions out of misc and use the ones in the
file systopolgy.py
- Add function collapse_cpulist(cpulist) outside of the CpuList
class
- Make methods longest_sequence and expand_cpulist accesible outside of
their class
- Add function online_cpus(self) to class SysTopology
- Add function online_cpus_str(self) to class SysTopology
- Add function invert_cpulist(self, cpulist) to class SysTopology
- Convert strings to f-strings for better readability
- Add a few missing docstrings to methods / functions, module etc
- Add a few more tests to the unit test
TODO: CpuList is suited for use by SysTopology, but is not ideal for a
generic CpuList. A more generally usable CpuList should be created
Signed-off-by: John Kacur <jkacur@redhat.com>
---
rteval/systopology.py | 90 +++++++++++++++++++++++++++++++++++--------
1 file changed, 74 insertions(+), 16 deletions(-)
diff --git a/rteval/systopology.py b/rteval/systopology.py
index e852f86e450f..ce8d02cf7318 100644
--- a/rteval/systopology.py
+++ b/rteval/systopology.py
@@ -23,11 +23,32 @@
# including keys needed to generate an equivalently functional executable
# are deemed to be part of the source code.
#
+""" Module for querying cpu cores and nodes """
import os
import os.path
import glob
+# Utility version of collapse_cpulist that doesn't require a CpuList object
+def collapse_cpulist(cpulist):
+ """ Collapse a list of cpu numbers into a string range
+ of cpus (e.g. 0-5, 7, 9) """
+ if len(cpulist) == 0:
+ return ""
+ idx = CpuList.longest_sequence(cpulist)
+ if idx == 0:
+ seq = str(cpulist[0])
+ else:
+ if idx == 1:
+ seq = f"{cpulist[0]},{cpulist[idx]}"
+ else:
+ seq = f"{cpulist[0]}-{cpulist[idx]}"
+
+ rest = collapse_cpulist(cpulist[idx+1:])
+ if rest == "":
+ return seq
+ return ",".join((seq, rest))
+
def sysread(path, obj):
""" Helper function for reading system files """
with open(os.path.join(path, obj), "r") as fp:
@@ -46,7 +67,7 @@ class CpuList:
if isinstance(cpulist, list):
self.cpulist = cpulist
elif isinstance(cpulist, str):
- self.cpulist = self.__expand_cpulist(cpulist)
+ self.cpulist = self.expand_cpulist(cpulist)
self.cpulist = self.online_cpulist(self.cpulist)
self.cpulist.sort()
@@ -67,7 +88,7 @@ class CpuList:
return False
@staticmethod
- def __longest_sequence(cpulist):
+ def longest_sequence(cpulist):
""" return index of last element of a sequence that steps by one """
lim = len(cpulist)
for idx, _ in enumerate(cpulist):
@@ -83,14 +104,14 @@ class CpuList:
"""
if len(cpulist) == 0:
return ""
- idx = self.__longest_sequence(cpulist)
+ idx = self.longest_sequence(cpulist)
if idx == 0:
seq = str(cpulist[0])
else:
if idx == 1:
- seq = "%d,%d" % (cpulist[0], cpulist[idx])
+ seq = f"{cpulist[0]},{cpulist[idx]}"
else:
- seq = "%d-%d" % (cpulist[0], cpulist[idx])
+ seq = f"{cpulist[0]}-{cpulist[idx]}"
rest = self.__collapse_cpulist(cpulist[idx+1:])
if rest == "":
@@ -98,7 +119,14 @@ class CpuList:
return ",".join((seq, rest))
@staticmethod
- def __expand_cpulist(cpulist):
+ def compress_cpulist(cpulist):
+ """ return a string representation of cpulist """
+ if isinstance(cpulist[0], int):
+ return ",".join(str(e) for e in cpulist)
+ return ",".join(cpulist)
+
+ @staticmethod
+ def expand_cpulist(cpulist):
""" expand a range string into an array of cpu numbers
don't error check against online cpus
"""
@@ -124,8 +152,8 @@ class CpuList:
def is_online(self, n):
""" check whether cpu n is online """
if n not in self.cpulist:
- raise RuntimeError("invalid cpu number %d" % n)
- path = os.path.join(CpuList.cpupath, 'cpu%d' % n)
+ raise RuntimeError(f"invalid cpu number {n}")
+ path = os.path.join(CpuList.cpupath, f'cpu{n}')
# Some hardware doesn't allow cpu0 to be turned off
if not os.path.exists(path + '/online') and n == 0:
@@ -240,8 +268,8 @@ class SysTopology:
return len(list(self.nodes.keys()))
def __str__(self):
- s = "%d node system" % len(list(self.nodes.keys()))
- s += " (%d cores per node)" % (len(self.nodes[list(self.nodes.keys())[0]]))
+ s = f"{len(list(self.nodes.keys()))} node system "
+ s += f"({(len(self.nodes[list(self.nodes.keys())[0]]))} cores per node)"
return s
def __contains__(self, node):
@@ -268,6 +296,7 @@ class SysTopology:
return n
def getinfo(self):
+ """ Initialize class Systopology """
nodes = glob.glob(os.path.join(SysTopology.nodepath, 'node[0-9]*'))
if nodes:
nodes.sort()
@@ -278,27 +307,56 @@ class SysTopology:
self.nodes[0] = SimNumaNode()
def getnodes(self):
+ """ return a list of nodes """
return list(self.nodes.keys())
def getcpus(self, node):
+ """ return a dictionary of cpus keyed with the node """
return self.nodes[node].getcpulist()
+ def online_cpus(self):
+ """ return a list of integers of all online cpus """
+ cpulist = []
+ for n in self.nodes:
+ cpulist += self.getcpus(n)
+ cpulist.sort()
+ return cpulist
+
+ def online_cpus_str(self):
+ """ return a list of strings of numbers of all online cpus """
+ cpulist = [str(cpu) for cpu in self.online_cpus()]
+ return cpulist
+
+ def invert_cpulist(self, cpulist):
+ """ return a list of online cpus not in cpulist """
+ return [c for c in self.online_cpus_str() if c not in cpulist]
if __name__ == "__main__":
def unit_test():
+ """ unit test, run python rteval/systopology.py """
s = SysTopology()
print(s)
- print("number of nodes: %d" % len(s))
+ print(f"number of nodes: {len(s)}")
for n in s:
- print("node[%d]: %s" % (n.nodeid, n))
- print("system has numa node 0: %s" % (0 in s))
- print("system has numa node 2: %s" % (2 in s))
- print("system has numa node 24: %s" % (24 in s))
+ print(f"node[{n.nodeid}]: {n}")
+ print(f"system has numa node 0: {0 in s}")
+ print(f"system has numa node 2: {2 in s}")
+ print(f"system has numa node 24: {24 in s}")
cpus = {}
+ print(f"nodes = {s.getnodes()}")
for node in s.getnodes():
cpus[node] = s.getcpus(int(node))
- print(f'cpus = {cpus}')
+ print(f'cpus = {cpus}')
+
+ onlcpus = s.online_cpus()
+ print(f'onlcpus = {onlcpus}')
+ onlcpus = collapse_cpulist(onlcpus)
+ print(f'onlcpus = {onlcpus}')
+
+ onlcpus_str = s.online_cpus_str()
+ print(f'onlcpus_str = {onlcpus_str}')
+ print(f"invert of [ 2, 4, 5 ] = {s.invert_cpulist([2, 3, 4])}")
unit_test()
--
2.37.3