From 5b55c62ff271e9d9278d25f027590aca05bff959 Mon Sep 17 00:00:00 2001 From: Crystal Wood Date: Thu, 20 Jun 2024 21:24:14 -0500 Subject: [PATCH 1/7] rteval: measurement: Remove ModuleInfo() All of the measurement modules have identical settings, and the use cases for deviating seem questionable. While we do have a desire to keep cyclictest and timerlat from running together, turning off run_parallel would prevent sysstat from running at the same time. And if there's a desire to run without loads, that seems like it belongs in the realm of user configuration, rather than anything inherent to a given measurement module. Any future module flags can be implemented similarly to what is done in load modules (e.g. set_exclusive). Places that checked with_loads now check whether a LoadModules container is present at all, which can be wired up to a command line option in the future. Signed-off-by: Crystal Wood Signed-off-by: John Kacur --- rteval/__init__.py | 39 ++++++------- rteval/modules/__init__.py | 13 +---- rteval/modules/measurement/__init__.py | 73 ++---------------------- rteval/modules/measurement/cyclictest.py | 5 -- rteval/modules/measurement/sysstat.py | 7 --- rteval/modules/measurement/timerlat.py | 5 -- 6 files changed, 26 insertions(+), 116 deletions(-) diff --git a/rteval/__init__.py b/rteval/__init__.py index 1a61148ef327..4a6883e28e5b 100644 --- a/rteval/__init__.py +++ b/rteval/__init__.py @@ -111,20 +111,21 @@ class RtEval(rtevalReport): except Exception as err: raise RuntimeError(f"Cannot create report directory (NFS with rootsquash on?) [{err}]]") - self.__logger.log(Log.INFO, "Preparing load modules") - params = {'workdir':self.__rtevcfg.workdir, - 'reportdir':self.__reportdir and self.__reportdir or "", - 'builddir':builddir, - 'srcdir':self.__rtevcfg.srcdir, - 'verbose': self.__rtevcfg.verbose, - 'debugging': self.__rtevcfg.debugging, - 'numcores':self._sysinfo.cpu_getCores(True), - 'logging':self.__rtevcfg.logging, - 'memsize':self._sysinfo.mem_get_size(), - 'numanodes':self._sysinfo.mem_get_numa_nodes(), - 'duration': float(self.__rtevcfg.duration), - } - self._loadmods.Setup(params) + if self._loadmods: + self.__logger.log(Log.INFO, "Preparing load modules") + params = {'workdir':self.__rtevcfg.workdir, + 'reportdir':self.__reportdir and self.__reportdir or "", + 'builddir':builddir, + 'srcdir':self.__rtevcfg.srcdir, + 'verbose': self.__rtevcfg.verbose, + 'debugging': self.__rtevcfg.debugging, + 'numcores':self._sysinfo.cpu_getCores(True), + 'logging':self.__rtevcfg.logging, + 'memsize':self._sysinfo.mem_get_size(), + 'numanodes':self._sysinfo.mem_get_numa_nodes(), + 'duration': float(self.__rtevcfg.duration), + } + self._loadmods.Setup(params) self.__logger.log(Log.INFO, "Preparing measurement modules") self._measuremods.Setup(params) @@ -136,13 +137,11 @@ class RtEval(rtevalReport): raise Exception("measure_profile is not an MeasurementProfile object") measure_start = None - (with_loads, run_parallel) = measure_profile.GetProfile() - self.__logger.log(Log.INFO, f"Using measurement profile [loads: {with_loads} parallel: {run_parallel}]") try: nthreads = 0 # start the loads - if with_loads: + if self._loadmods: self._loadmods.Start() print(f"rteval run on {os.uname()[2]} started at {time.asctime()}") @@ -168,7 +167,7 @@ class RtEval(rtevalReport): # Unleash the loads and measurement threads report_interval = int(self.__rtevcfg.report_interval) - if with_loads: + if self._loadmods: self._loadmods.Unleash() nthreads = threading.active_count() else: @@ -192,7 +191,7 @@ class RtEval(rtevalReport): self.__logger.log(Log.WARN, "Measurement threads did not use the full time slot. Doing a controlled stop.") - if with_loads: + if nthreads: if threading.active_count() < nthreads: raise RuntimeError("load thread died!") @@ -222,7 +221,7 @@ class RtEval(rtevalReport): measure_profile.Stop() # stop the loads - if with_loads: + if self._loadmods: self._loadmods.Stop() print(f"stopping run at {time.asctime()}") diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py index 4330a839db6f..0c0ce7202f77 100644 --- a/rteval/modules/__init__.py +++ b/rteval/modules/__init__.py @@ -269,14 +269,6 @@ reference from the first import""" return mod - def ModuleInfo(self, modname, modroot=None): - """Imports a module and calls the modules' ModuleInfo() function and returns -the information provided by the module""" - - mod = self.LoadModule(modname, modroot) - return mod.ModuleInfo() - - def SetupModuleOptions(self, parser, config): """Sets up a separate argparse ArgumentGroup per module with its supported parameters""" @@ -495,9 +487,8 @@ class RtEvalModules: def Unleash(self): - """Unleashes all the loaded modules workloads""" + """Unleashes all the loaded modules""" - # turn loose the loads nthreads = 0 self._logger.log(Log.INFO, f"Sending start event to all {self._module_type} modules") for (modname, mod) in self.__modules: @@ -508,7 +499,7 @@ class RtEvalModules: return nthreads - def _isAlive(self): + def isAlive(self): """Returns True if all modules are running""" for (modname, mod) in self.__modules: diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py index 43c0fda30ce1..7b1d84ef554d 100644 --- a/rteval/modules/measurement/__init__.py +++ b/rteval/modules/measurement/__init__.py @@ -11,24 +11,13 @@ import rteval.cpulist_utils as cpulist_utils class MeasurementProfile(RtEvalModules): """Keeps and controls all the measurement modules with the same measurement profile""" - def __init__(self, config, with_load, run_parallel, modules_root, logger): - self.__with_load = with_load - self.__run_parallel = run_parallel - - # Only used when running modules serialised - self.__run_serialised_mods = None - + def __init__(self, config, modules_root, logger): self._module_type = "measurement" self._module_config = "measurement" self._report_tag = "Profile" RtEvalModules.__init__(self, config, modules_root, logger) - def GetProfile(self): - "Returns the profile characteristic as (with_load, run_parallel)" - return (self.__with_load, self.__run_parallel) - - def ImportModule(self, module): "Imports an exported module from a ModuleContainer() class" return self._ImportModule(module) @@ -41,54 +30,6 @@ class MeasurementProfile(RtEvalModules): self._RegisterModuleObject(modname, modobj) - def Unleash(self): - """Unleashes all the measurement modules""" - - if self.__run_parallel: - # Use the inherrited method if running - # measurements in parallel - return RtEvalModules.Unleash(self) - - # Get a list of all registered modules, - # and start the first one - self.__serialised_mods = self.GetModulesList() - mod = self.GetNamedModuleObject(self.__serialised_mods[0]) - mod.setStart() - return 1 - - - def MakeReport(self): - "Generates an XML report for all run measurement modules in this profile" - rep_n = RtEvalModules.MakeReport(self) - rep_n.newProp("loads", self.__with_load and "1" or "0") - rep_n.newProp("parallel", self.__run_parallel and "1" or "0") - return rep_n - - - def isAlive(self): - """Returns True if all modules which are supposed to run runs""" - - if self.__run_parallel: - return self._isAlive() - - if self.__serialised_mods: - # If running serialised, first check if measurement is still running, - # if so - return True. - mod = self.GetNamedModuleObject(self.__serialised_mods[0]) - if mod.WorkloadAlive(): - return True - - # If not, go to next on the list and kick it off - self.__serialised_mods.remove(self.__serialised_mods[0]) - if self.__serialised_mods: - mod = self.GetNamedModuleObject(self.__serialised_mods[0]) - mod.setStart() - return True - - # If we've been through everything, nothing is running - return False - - class MeasurementModules: """Class which takes care of all measurement modules and groups them into measurement profiles, based on their characteristics""" @@ -116,13 +57,11 @@ measurement profiles, based on their characteristics""" self.__container.LoadModule(m[0]) - def GetProfile(self, with_load, run_parallel): + def GetProfile(self): "Returns the appropriate MeasurementProfile object, based on the profile type" for p in self.__measureprofiles: - mp = p.GetProfile() - if mp == (with_load, run_parallel): - return p + return p return None @@ -154,15 +93,13 @@ measurement profiles, based on their characteristics""" for (modname, modtype) in modcfg: if isinstance(modtype, str) and modtype.lower() == 'module': # Only 'module' will be supported (ds) - # Extract the measurement modules info - modinfo = self.__container.ModuleInfo(modname) + self.__container.LoadModule(modname) # Get the correct measurement profile container for this module - mp = self.GetProfile(modinfo["loads"], modinfo["parallel"]) + mp = self.GetProfile() if mp is None: # If not found, create a new measurement profile mp = MeasurementProfile(self.__cfg, - modinfo["loads"], modinfo["parallel"], self.__modules_root, self.__logger) self.__measureprofiles.append(mp) diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py index 3301e1b45e11..3a34c1b988d6 100644 --- a/rteval/modules/measurement/cyclictest.py +++ b/rteval/modules/measurement/cyclictest.py @@ -394,11 +394,6 @@ class Cyclictest(rtevalModulePrototype): return rep_n -def ModuleInfo(): - return {"parallel": True, - "loads": True} - - def ModuleParameters(): """ default parameters """ return {"interval": {"descr": "Base interval of the threads in microseconds", diff --git a/rteval/modules/measurement/sysstat.py b/rteval/modules/measurement/sysstat.py index d4646c1646f4..a0efd8953659 100644 --- a/rteval/modules/measurement/sysstat.py +++ b/rteval/modules/measurement/sysstat.py @@ -93,13 +93,6 @@ class sysstat(rtevalModulePrototype): -def ModuleInfo(): - # sysstat features - run in parallel with outher measurement modules with loads - return {"parallel": True, - "loads": True} - - - def ModuleParameters(): return {} # No arguments available diff --git a/rteval/modules/measurement/timerlat.py b/rteval/modules/measurement/timerlat.py index dc6226ccc991..f3bdc7098bc0 100644 --- a/rteval/modules/measurement/timerlat.py +++ b/rteval/modules/measurement/timerlat.py @@ -499,11 +499,6 @@ class Timerlat(rtevalModulePrototype): return rep_n -def ModuleInfo(): - """ Required measurement module information """ - return {"parallel": True, - "loads": True} - def ModuleParameters(): """ default parameters """ return {"priority": {"descr": "Run rtla timerlat with this priority", -- 2.45.2