325 lines
12 KiB
Diff
325 lines
12 KiB
Diff
|
From 5b55c62ff271e9d9278d25f027590aca05bff959 Mon Sep 17 00:00:00 2001
|
||
|
From: Crystal Wood <crwood@redhat.com>
|
||
|
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 <crwood@redhat.com>
|
||
|
Signed-off-by: John Kacur <jkacur@redhat.com>
|
||
|
---
|
||
|
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
|
||
|
|