aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClark Williams <williams@redhat.com>2015-06-10 11:52:53 -0500
committerClark Williams <williams@redhat.com>2015-06-10 11:52:53 -0500
commitf2599820709edc986d5dcd9d383a6e3caec686d1 (patch)
tree70813f5950a08a0349bef911122653321ff76ed4
parent2bc5c0963cbee36ed303415dbef9f55084364b30 (diff)
parent96eea39f23e917621afe3982e41c917965b6c43b (diff)
downloadrteval-f2599820709edc986d5dcd9d383a6e3caec686d1.tar.gz
Merge branch 'v2.0-work' into v2.0
-rw-r--r--rteval/misc.py63
-rw-r--r--rteval/modules/__init__.py2
-rw-r--r--rteval/modules/loads/__init__.py2
-rw-r--r--rteval/modules/loads/hackbench.py4
-rw-r--r--rteval/modules/loads/kcompile.py4
-rw-r--r--rteval/modules/measurement/cyclictest.py72
6 files changed, 119 insertions, 28 deletions
diff --git a/rteval/misc.py b/rteval/misc.py
new file mode 100644
index 0000000..062355a
--- /dev/null
+++ b/rteval/misc.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python -tt
+#
+# Copyright (C) 2015 Clark Williams <clark.williams@gmail.com>
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+import os
+import glob
+
+# expand a string range into a list
+# don't error check against online cpus
+def expand_cpulist(cpulist):
+ '''expand a range string into an array of cpu numbers'''
+ result = []
+ for part in cpulist.split(','):
+ if '-' in part:
+ a, b = part.split('-')
+ a, b = int(a), int(b)
+ result.extend(range(a, b + 1))
+ else:
+ a = int(part)
+ result.append(a)
+ return [ str(i) for i in list(set(result)) ]
+
+def online_cpus():
+ return [ str(c.replace('/sys/devices/system/cpu/cpu', '')) for c in glob.glob('/sys/devices/system/cpu/cpu[0-9]*') ]
+
+def cpuinfo():
+ core = -1
+ info = {}
+ for l in open('/proc/cpuinfo'):
+ l = l.strip()
+ if not l: continue
+ key,val = [ i.strip() for i in l.split(':')]
+ if key == 'processor':
+ core = val
+ info[core] = {}
+ continue
+ info[core][key] = val
+ return info
+
+if __name__ == "__main__":
+
+ info = cpuinfo()
+ idx = info.keys()
+ idx.sort()
+ for i in idx:
+ print "%s: %s" % (i, info[i])
+
+ print "0: %s" % (info['0']['model name'])
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py
index cad593c..12a544b 100644
--- a/rteval/modules/__init__.py
+++ b/rteval/modules/__init__.py
@@ -270,7 +270,7 @@ the information provided by the module"""
grparser = optparse.OptionGroup(parser, "Group Options for %s modules" % self.__modtype)
grparser.add_option('--%s-cpulist' % self.__modtype,
- dest='%s___cpulist' % self.__modtype, action='store',
+ dest='%s___cpulist' % self.__modtype, action='store', default="",
help='CPU list where %s modules will run' % self.__modtype,
metavar='LIST')
parser.add_option_group(grparser)
diff --git a/rteval/modules/loads/__init__.py b/rteval/modules/loads/__init__.py
index 29754c6..040acc0 100644
--- a/rteval/modules/loads/__init__.py
+++ b/rteval/modules/loads/__init__.py
@@ -50,7 +50,7 @@ class LoadThread(rtevalModulePrototype):
self.source = config.setdefault('source', None)
self.reportdir = config.setdefault('reportdir', os.getcwd())
self.memsize = config.setdefault('memsize', (0, 'GB'))
- self.cpulist = config.setdefault('cpulist', None)
+ self.cpulist = config.setdefault('cpulist', "")
self._logging = config.setdefault('logging', True)
self._cfg = config
self.mydir = None
diff --git a/rteval/modules/loads/hackbench.py b/rteval/modules/loads/hackbench.py
index 4b896d1..f937e94 100644
--- a/rteval/modules/loads/hackbench.py
+++ b/rteval/modules/loads/hackbench.py
@@ -53,11 +53,11 @@ class Hackbench(CommandLineLoad):
mult = 0
self._donotrun = True
- if self._cfg.has_key('cpulist'):
+ if self._cfg.has_key('cpulist') and self._cfg.cpulist:
cpulist = self._cfg.cpulist
self.jobs = len(expand_cpulist(cpulist)) * mult
else:
- cpulist = None
+ cpulist = ""
self.jobs = self.num_cpus * mult
self.args = ['hackbench', '-P',
diff --git a/rteval/modules/loads/kcompile.py b/rteval/modules/loads/kcompile.py
index 3ac0d53..1eb2cde 100644
--- a/rteval/modules/loads/kcompile.py
+++ b/rteval/modules/loads/kcompile.py
@@ -137,11 +137,11 @@ class Kcompile(CommandLineLoad):
else:
self.__outfd = self.__errfd = self.__nullfd
- if self._cfg.has_key('cpulist'):
+ if self._cfg.has_key('cpulist') and self._cfg.cpulist:
cpulist = self._cfg.cpulist
self.num_cpus = len(expand_cpulist(cpulist))
else:
- cpulist = None
+ cpulist = ""
self.jobs = self.__calc_numjobs()
self._log(Log.DEBUG, "starting loop (jobs: %d)" % self.jobs)
diff --git a/rteval/modules/measurement/cyclictest.py b/rteval/modules/measurement/cyclictest.py
index a15f6e7..f596665 100644
--- a/rteval/modules/measurement/cyclictest.py
+++ b/rteval/modules/measurement/cyclictest.py
@@ -28,7 +28,7 @@
import os, sys, subprocess, signal, libxml2, shutil, tempfile, time
from rteval.Log import Log
from rteval.modules import rtevalModulePrototype
-
+from rteval.misc import expand_cpulist, online_cpus, cpuinfo
class RunData(object):
'''class to keep instance data from a cyclictest run'''
@@ -50,6 +50,17 @@ class RunData(object):
self.__mad = 0.0
self._log = logfnc
+ def __str__(self):
+ retval = "id: %s\n" % self.__id
+ retval += "type: %s\n" % self.__type
+ retval += "numsamples: %d\n" % self.__numsamples
+ retval += "min: %d\n" % self.__min
+ retval += "max: %d\n" % self.__max
+ retval += "stddev: %f\n" % self.__stddev
+ retval += "mad: %f\n" % self.__mad
+ retval += "mean: %f\n" % self.__mean
+ return retval
+
def sample(self, value):
self.__samples[value] += self.__samples.setdefault(value, 0) + 1
if value > self.__max: self.__max = value
@@ -175,28 +186,40 @@ class Cyclictest(rtevalModulePrototype):
self.__cfg = config
# Create a RunData object per CPU core
- f = open('/proc/cpuinfo')
self.__numanodes = int(self.__cfg.setdefault('numanodes', 0))
self.__priority = int(self.__cfg.setdefault('priority', 95))
self.__buckets = int(self.__cfg.setdefault('buckets', 2000))
self.__numcores = 0
+ self.__cpus = []
self.__cyclicdata = {}
- for line in f:
- if line.startswith('processor'):
- core = line.split()[-1]
- self.__cyclicdata[core] = RunData(core, 'core',self.__priority,
- logfnc=self._log)
- self.__numcores += 1
- if line.startswith('model name'):
- desc = line.split(': ')[-1][:-1]
- self.__cyclicdata[core].description = ' '.join(desc.split())
- f.close()
+ self.__sparse = False
+
+ if self.__cfg.cpulist:
+ self.__cpulist = self.__cfg.cpulist
+ self.__cpus = expand_cpulist(self.__cpulist)
+ self.__sparse = True
+ else:
+ self.__cpus = online_cpus()
+
+ self.__numcores = len(self.__cpus)
+
+ info = cpuinfo()
+
+ # create a RunData object for each core we'll measure
+ for core in self.__cpus:
+ self.__cyclicdata[core] = RunData(core, 'core',self.__priority,
+ logfnc=self._log)
+ self.__cyclicdata[core].description = info[core]['model name']
# Create a RunData object for the overall system
self.__cyclicdata['system'] = RunData('system', 'system', self.__priority,
logfnc=self._log)
- self.__cyclicdata['system'].description = ("(%d cores) " % self.__numcores) + self.__cyclicdata['0'].description
- self._log(Log.DEBUG, "system has %d cpu cores" % self.__numcores)
+ self.__cyclicdata['system'].description = ("(%d cores) " % self.__numcores) + info['0']['model name']
+
+ if self.__sparse:
+ self._log(Log.DEBUG, "system using %d cpu cores" % self.__numcores)
+ else:
+ self._log(Log.DEBUG, "system has %d cpu cores" % self.__numcores)
self.__started = False
self.__cyclicoutput = None
self.__breaktraceval = None
@@ -239,8 +262,12 @@ class Cyclictest(rtevalModulePrototype):
'-qmu',
'-h %d' % self.__buckets,
"-p%d" % int(self.__priority),
- self.__getmode(),
]
+ if self.__sparse:
+ self.__cmd.append('-t%d' % self.__numcores)
+ self.__cmd.append('-a%s' % self.__cpulist)
+ else:
+ self.__cmd.append(self.__getmode())
if self.__cfg.has_key('threads') and self.__cfg.threads:
self.__cmd.append("-t%d" % int(self.__cfg.threads))
@@ -309,12 +336,15 @@ class Cyclictest(rtevalModulePrototype):
continue
index = int(vals[0])
- for i in range(0, len(self.__cyclicdata)-1):
- if str(i) not in self.__cyclicdata: continue
- self.__cyclicdata[str(i)].bucket(index, int(vals[i+1]))
+ for i,core in enumerate(self.__cpus):
+ self.__cyclicdata[core].bucket(index, int(vals[i+1]))
self.__cyclicdata['system'].bucket(index, int(vals[i+1]))
+
+ # generate statistics for each RunData object
for n in self.__cyclicdata.keys():
+ #print "reducing self.__cyclicdata[%s]" % n
self.__cyclicdata[n].reduce()
+ #print self.__cyclicdata[n]
# If the breaktrace feature of cyclictest was enabled and triggered,
# put the trace into the log directory
@@ -361,10 +391,9 @@ class Cyclictest(rtevalModulePrototype):
rep_n.addChild(abrt_n)
rep_n.addChild(self.__cyclicdata["system"].MakeReport())
- for thr in range(0, self.__numcores):
+ for thr in self.__cpus:
if str(thr) not in self.__cyclicdata:
continue
-
rep_n.addChild(self.__cyclicdata[str(thr)].MakeReport())
return rep_n
@@ -400,7 +429,7 @@ def create(params, logger):
if __name__ == '__main__':
from rteval.rtevalConfig import rtevalConfig
-
+
l = Log()
l.SetLogVerbosity(Log.INFO|Log.DEBUG|Log.ERR|Log.WARN)
@@ -422,7 +451,6 @@ if __name__ == '__main__':
c._WorkloadSetup()
c._WorkloadPrepare()
c._WorkloadTask()
- print "Running for %i seconds" % runtime
time.sleep(runtime)
c._WorkloadCleanup()
rep_n = c.MakeReport()