summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xexec.py4
-rw-r--r--numbench/benchchildren.py10
-rw-r--r--numbench/benchconfig.py114
-rw-r--r--numbench/benchprint.py79
-rw-r--r--numbench/confinput/__init__.py11
-rw-r--r--numbench/confinput/oldinput.py69
-rw-r--r--numbench/confinput/xmlinput.py159
-rw-r--r--numbench/main.py104
-rw-r--r--numbench/report.py44
-rw-r--r--numbench/reports/html.py6
-rw-r--r--numbench/utils/benchutils.py18
-rw-r--r--numbench/utils/envread.py4
-rw-r--r--numbench/utils/portageutils.py30
-rw-r--r--numbench/xmlinput.py170
14 files changed, 408 insertions, 414 deletions
diff --git a/exec.py b/exec.py
index c3b7eda..1b794dd 100755
--- a/exec.py
+++ b/exec.py
@@ -18,4 +18,6 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-import numbench.main \ No newline at end of file
+#@PydevCodeAnalysisIgnore
+
+import numbench.main
diff --git a/numbench/benchchildren.py b/numbench/benchchildren.py
index 1686639..9f27979 100644
--- a/numbench/benchchildren.py
+++ b/numbench/benchchildren.py
@@ -15,16 +15,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-try:
- copy = procs
- del copy
-except:
+
+if 'procs' not in locals():
procs = []
-
+
def terminate():
for p in procs:
if p.poll() is None:
p.kill()
def append(proc):
- procs.append(proc) \ No newline at end of file
+ procs.append(proc)
diff --git a/numbench/benchconfig.py b/numbench/benchconfig.py
index e7cc62a..dc6e9b4 100644
--- a/numbench/benchconfig.py
+++ b/numbench/benchconfig.py
@@ -18,13 +18,77 @@
import sys, os, time, subprocess as sp
from os.path import join as pjoin
-if not locals().has_key('initialized'):
- initialized = True
- isroot = os.getuid() == 0
+# Arguments
+arguments = None
+inputfile = None
+clean = None
+imageformat = None
+
+# Directories
+curdir = None
+scriptdir = None
+btldir = None
+libdir = None
+
+# Storage directories
+basedir = None
+testsdir = None
+rootsdir = None
+pkgsdir = None
+reportdir = None
+logdir = None
+
+# Module
+module = None
+modulename = None
+moduleargs = None
+
+# Other
+isroot = not os.getuid()
+tests = None
+
+
+def parseArguments():
+ global arguments, inputfile, clean, imageformat, basedir
+
+ arguments = []
+ clean = False
+ imageformat = 'svg'
+
+
+ skipargs = 0
+ for i, a in enumerate(sys.argv[1:], 1):
+ if skipargs > 0:
+ skipargs -= 1
+ continue
+
+ if a[0] != '-':
+ inputfile = os.path.realpath(a)
+ continue
+
+ if a in ('-d', '--directory'):
+ basedir = pjoin(curdir, sys.argv[i + 1])
+ skipargs += 1
+ continue
+
+ if a in ('-c', '--clean'):
+ clean = True
+ continue
+
+ if a in ('-i', '--imageformat'):
+ imageformat = sys.argv[i + 1]
+ skipargs += 1
+ continue
+
+ arguments.append(a)
+
+
+
+def setDirs():
+ global curdir, scriptdir, btldir, libdir, basedir
+ global testsdir, rootsdir, pkgsdir, reportdir, logdir
- modulename = sys.argv[1]
- inputfile = os.path.realpath(sys.argv[2])
# Script directories
curdir = os.path.abspath('.')
@@ -43,42 +107,15 @@ if not locals().has_key('initialized'):
else:
libdir = 'usr/' + libdir
- # Parse arguments
- passargs = []
- skipargs = 0
- for i,a in enumerate(sys.argv[3:], 3):
- if skipargs > 0:
- skipargs -= 1
- continue
-
- if a in ('-d', '--directory'):
- basedir = pjoin(curdir, sys.argv[i+1])
- skipargs += 1
- continue
-
- if a in ('-c', '--clean'):
- clean = True
- continue
-
- if a in ('-i', '--imageformat'):
- imageformat = sys.argv[i+1]
- skipargs += 1
- continue
-
- passargs.append(a)
-
- # Clean flag
- if not locals().has_key('clean'):
- clean = False
-
- # Image format
- if not locals().has_key('imageformat'):
- imageformat = 'svg'
-
# Storage directories
- if not locals().has_key('basedir'):
+ if basedir is None:
+ if modulename is None:
+ raise RuntimeError("Module is not defined")
+
basedirb = pjoin(os.environ['HOME'], '.numbench') \
+ '/numbench_' + modulename + '_' + time.strftime('%Y-%m-%d')
+
+ # Find suitable base directory
if os.path.exists(basedirb):
n = 1
while True:
@@ -92,4 +129,3 @@ if not locals().has_key('initialized'):
testsdir, rootsdir, pkgsdir, reportdir, logdir = tuple([pjoin(basedir, i) \
for i in ('tests', 'roots', 'packages', 'report', 'log')])
-
diff --git a/numbench/benchprint.py b/numbench/benchprint.py
index 0cbd0b6..8ccd0e8 100644
--- a/numbench/benchprint.py
+++ b/numbench/benchprint.py
@@ -15,46 +15,43 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-try:
- needsinitialization = not initialized
-except NameError:
- needsinitialization = True
-
-
-if needsinitialization:
- import benchconfig as cfg
- from utils import benchutils as bu
- from os.path import dirname, join as pjoin
-
- class _Print:
- def __init__(self, logfile, maxlevel=10):
- self._level = 0
- self._maxlevel = maxlevel
- self._logfile = logfile
-
- def __call__(self, arg='', end='\n'):
- printstr = str(arg) + end
- if self._level > 0:
- printstr = (self._level-1)*" " + "-- " + printstr
-
- # Print to logfile
- bu.mkdir(dirname(self._logfile))
- logfile = file(self._logfile, 'a')
- print >> logfile, printstr,
- logfile.close()
-
- # Print to terminal
- if self._level <= self._maxlevel:
- print printstr,
-
- def up(self, n=1):
- self._level = max(self._level-n, 0)
-
- def down(self, n=1):
- self._level = max(self._level+n, 0)
-
- # Initialize main Print object ("static")
- Print = _Print(pjoin(cfg.logdir, 'main.log'), 3)
+import benchconfig as cfg
+from utils import benchutils as bu
+from os.path import dirname, join as pjoin
+
+class _Print:
+ def __init__(self, logfile, maxlevel=10):
+ self._level = 0
+ self._maxlevel = maxlevel
+ self._logfile = logfile
+
+ def __call__(self, arg='', end='\n'):
+ printstr = str(arg) + end
+ if self._level > 0:
+ printstr = (self._level - 1) * " " + "-- " + printstr
+
+ # Print to logfile
+ bu.mkdir(dirname(self._logfile))
+ logfile = file(self._logfile, 'a')
+ print >> logfile, printstr,
+ logfile.close()
+
+ # Print to terminal
+ if self._level <= self._maxlevel:
+ print printstr,
+
+ def up(self, n=1):
+ self._level = max(self._level - n, 0)
+
+ def down(self, n=1):
+ self._level = max(self._level + n, 0)
+
+# Uninitialized object (wait for argument parsing, directories lookup,... )
+Print = None
+
+def initializePrint():
+ global Print
+ Print = _Print(pjoin(cfg.logdir, 'main.log'), 3)
-initialized = True
+ return Print
diff --git a/numbench/confinput/__init__.py b/numbench/confinput/__init__.py
deleted file mode 100644
index 4fbee33..0000000
--- a/numbench/confinput/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from os.path import basename
-
-def parseInput(fname):
- term = basename(fname).rsplit('.')[-1]
-
- if term.lower() == 'xml':
- import xmlinput as parser
- else:
- import oldinput as parser
-
- return parser.parseConf(fname) \ No newline at end of file
diff --git a/numbench/confinput/oldinput.py b/numbench/confinput/oldinput.py
deleted file mode 100644
index 8d903c0..0000000
--- a/numbench/confinput/oldinput.py
+++ /dev/null
@@ -1,69 +0,0 @@
-def readEnvFile(fname):
- """Reads a bash file with void environment and returns the environment
- at the end of the execution."""
- proc = sp.Popen('. '+fname+' &> /dev/null; env', \
- shell=True, stdout=sp.PIPE, env={})
- lines = proc.stdout.read().split('\n')[:-1]
- env = dict([l.split('=', 1) for l in lines])
-
- for k in ('SHLVL', 'PWD', '_'):
- if env.has_key(k):
- del env[k]
- return env
-
-def parseConf(fname):
- input = file(fname).read()
-
- tests = {}
- for line in input.split('\n'):
- line = line.strip()
- spl = [i.strip() for i in shlex.split(line)]
- if len(spl) < 2:
- continue
- if line[0] == '#':
- continue
- env = {}
- skip = []
- change = {}
- descr = None
- fileenv = {}
-
- # Interpret arguments
- for var in spl[2:]:
-
- # if begins with '-': skip implementation
- if var[0] == '-':
- skip.append(var[1:])
-
- # if key:value, substitute pkg-config dependency
- elif ':' in var and not '=' in var:
- c_0, c_1 = var.split(':', 1)
- change[c_0] = c_1
-
- # if descr|text set description (for future use)
- elif var[:6] == 'descr|':
- descr = var[6:]
-
- # if @file: read bash script and set env
- elif var[0] == '@':
- fileenvNew = readEnvFile(pjoin(cfg.curdir, var[1:]))
- fileenv = dict( fileenv.items() + fileenvNew.items() )
- del fileenvNew
-
- # Otherwise, assume key=value syntax
- else:
- e_0, e_1 = var.split('=', 1)
- env[e_0] = e_1
-
- # Set environment (argument overrides bash file)
- env = dict( fileenv.items() + env.items() )
-
- try:
- # Insert test
- avail = available_packages(spl[1])[-1]
- tests[spl[0]] = {'package':avail , 'emergeenv':env, 'skip':skip, \
- 'requires':change, 'descr':descr}
- except:
- # Or trigger an non-fatal error
- sys.stderr.write('Error: package ' + spl[1] + ' not found\n')
- return tests \ No newline at end of file
diff --git a/numbench/confinput/xmlinput.py b/numbench/confinput/xmlinput.py
deleted file mode 100644
index cb82e5c..0000000
--- a/numbench/confinput/xmlinput.py
+++ /dev/null
@@ -1,159 +0,0 @@
-import xml.dom.minidom
-import sys, os, portage, types
-import subprocess as sp
-from os.path import join as pjoin, dirname as pdirname, realpath as prealpath
-
-from .. import benchconfig as cfg
-from ..utils import portageutils as pu
-
-
-def readFile(fs):
- result = {}
-
- # If fs is a filename, open it
- if type(fs) != types.FileType:
- fs = file(pjoin(cfg.curdir, fs))
-
- # Read line by line
- for l in fs.readlines():
- try:
- k,v = l.split('=', 1)
- result[k.strip()] = v.strip()
- except:
- pass
-
- return result
-
-
-def readScript(fname):
- fname = pjoin(cfg.curdir, fname)
-
- # Execute script with void environment
- proc = sp.Popen('. ' + fname + ' &> /dev/null; env', shell=True,
- stdout=sp.PIPE, env={})
- result = readFile(proc.stdout)
-
- # Remove useless variables
- for k in ('SHLVL', 'PWD', '_'):
- if result.has_key(k):
- del result[k]
- return result
-
-def getEnvFromNode(node, envName):
- envs = node.getElementsByTagName(envName)
-
- # Check number of envs
- if len(envs) > 1:
- errstr = "Error: no more than one " + envName + " element is allowed!"
- raise Exception(errstr)
- elif len(envs) < 1:
- return {}
-
- e = envs[0]
-
- # Check attribute "append"
- if (e.attributes.has_key('append')):
- append = e.attributes['append'].value == '1'
- else:
- append = False
-
- if append:
- env = os.environ
- else:
- env = {}
-
- # Check attribute script
- # the script is run with a void environment
- if (e.attributes.has_key('script')):
- for k,v in readScript(e.getAttribute('script')).items():
- env[k] = v
-
- # Check attribute file
- # the file must contain lines with key=value pairs (each line one pair)
- if (e.attributes.has_key('file')):
- for k,v in readFile(e.getAttribute('file')).items():
- env[k] = v
-
- # Get Variables
- for v in e.getElementsByTagName('var'):
- envname = v.getAttribute('name')
- envvalue = v.firstChild.data
- env[envname] = envvalue
-
- return env
-
-
-def parseConf(fname):
- testNodes = xml.dom.minidom.parse(fname).getElementsByTagName('test')
-
- tests = {}
-
- for t in testNodes:
- tid = t.getAttribute('id')
-
- # Get description
- descr = None
- if len(t.getElementsByTagName('descr')) != 0:
- descr = t.getElementsByTagName('descr')[0].firstChild.data
-
- # Get package
- pkg = portage.catpkgsplit(
- t.getElementsByTagName('pkg')[0].firstChild.data)
- normPkg = pu.normalize_cpv(pkg)
-
- # Skip implementations
- skip = []
- skipre = []
- for s in t.getElementsByTagName('skip'):
- if not s.hasAttribute('type') or s.getAttribute('type') == 'glob':
- skip.append(s.firstChild.data)
- elif s.getAttribute('type') == 'regexp':
- skipre.append(s.firstChild.data)
- else:
- sys.stderr.write('Error in configuration file: skip type ' \
- + s.getAttribute('type') + ' not supported')
-
- # Requirements
- requires = {}
- for i in t.getElementsByTagName('required'):
- requires[i.getAttribute('name').strip()] = i.firstChild.data.strip()
-
- # Environments
- dependenv = getEnvFromNode(t, 'dependenv')
- emergeenv = getEnvFromNode(t, 'emergeenv')
- compileenv = getEnvFromNode(t, 'compileenv')
- runenv = getEnvFromNode(t, 'runenv')
-
- # Adjust PATH
- if compileenv.has_key('PATH'):
- compileenv['PATH'] += ':' + os.environ['PATH']
- else:
- compileenv['PATH'] = os.environ['PATH']
-
- if runenv.has_key('PATH'):
- runenv['PATH'] += ':' + os.environ['PATH']
- else:
- runenv['PATH'] = os.environ['PATH']
-
- # Build test dictionary
- tests[tid] = dict(
- descr = descr,
- package = pkg,
- normalizedPackage = normPkg,
- skip = skip,
- skipre = skipre,
- requires = requires,
-
- dependenv = dependenv,
- emergeenv = emergeenv,
- compileenv = compileenv,
- runenv = runenv,
-
- pkgdir = pjoin(cfg.pkgsdir, tid),
- archive = pjoin(cfg.pkgsdir, tid, normPkg+'.tbz2'),
- root = pjoin(cfg.rootsdir, tid),
- testdir = pjoin(cfg.testsdir, tid),
- logdir = pjoin(cfg.logdir, tid)
- )
-
- return tests
diff --git a/numbench/main.py b/numbench/main.py
index bbd9b1f..3b22701 100644
--- a/numbench/main.py
+++ b/numbench/main.py
@@ -26,7 +26,7 @@ def close(*args):
benchchildren.terminate()
Print._level = 0
Print()
- Print(80*'-')
+ Print(80 * '-')
Print("INTERRUPT TRIGGERED")
Print("Exiting")
exit(0)
@@ -39,21 +39,31 @@ def print_usage():
def print_help():
- print "Usage: numbench module conffile [options]"
+ print "Usage: numbench conffile [options]"
print " numbench [ -h | --help ]"
print " numbench module [ -h | --help ]"
print
print "Options:"
- print " [ -h | --help ] - Display an help message"
+ print " [ -h | --help ] - Displays an help message."
+ print
+ print " [ -d | --directory] dir - Stores the data in the given directory."
+ print " If not given, a directory in ~/.numbench is chosen."
+ print
+ print " [ -c | --clean] - Removes the temporary data."
+ print
+ print " [ -i | --imageformat] format - Selects the given format for the"
+ print " resulting images. Available are png, svg, eps, ps, pdf."
+ print " Default is svg."
print
print "Modules:"
print " blas - Test BLAS implementations"
print " cblas - Test CBLAS implementations"
print " lapack - Test LAPACK implementations"
- #print " scalapack - Test the ScaLAPACK library"
+ print " lapacke - Test LAPACK implementations"
+ print " scalapack - Test the ScaLAPACK library"
#print " blas_accuracy - Test BLAS implementations for accuracy"
#print " lapack_accuracy - Test LAPACK implementations for accuracy"
- #print " fftw - Test the FFTW library"
+ print " fftw - Test the FFTW library"
#print " metis - Test the METIS tools"
print
print "More information about a module is available through the command:"
@@ -61,7 +71,7 @@ def print_help():
def loadModule(modulename):
- tmp = __import__('numbench.modules.'+modulename, fromlist = ['Module'])
+ tmp = __import__('numbench.modules.' + modulename, fromlist=['Module'])
# try:
# tmp = __import__('numbench.modules.'+modulename, fromlist = ['Module'])
# except ImportError as e:
@@ -75,15 +85,16 @@ def loadModule(modulename):
## PRINT HELP IF NEEDED
# If no argument or '-h' is given, print the help
-if len(sys.argv) < 3 or sys.argv[1] in ('-h', '--help'):
+if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'):
print_help()
exit(0)
# If requested, print the module help
-if sys.argv[2] in ('-h', '--help'):
- tmp = loadModule(sys.argv[1])
- tmp.Module.printHelp()
- exit(0)
+# TODO: print module's help
+#if sys.argv[2] in ('-h', '--help'):
+# tmp = loadModule(sys.argv[1])
+# tmp.Module.printHelp()
+# exit(0)
## BEGIN THE TRUE SCRIPT
@@ -93,26 +104,43 @@ import re
from fnmatch import fnmatch
from os.path import join as pjoin
-import benchconfig as cfg, confinput, report
+import benchconfig as cfg
+from xmlinput import Parser
from utils import envread, benchutils as bu, portageutils as pu
-from benchprint import Print
+import benchprint
+## Set-up the run configuration
-# Parse the configuration file
+# Parse the arguments
+cfg.parseArguments()
+
+# Start configuration parser
if not os.path.exists(cfg.inputfile):
sys.stderr.write("File not found: " + cfg.inputfile)
print_usage()
exit(1)
-cfg.tests = confinput.parseInput(cfg.inputfile)
+parser = Parser(cfg.inputfile)
+
+# Get module name and arguments
+cfg.modulename = parser.getModuleName()
+cfg.moduleargs = parser.getModuleArguments()
+
+# Set-up directories
+cfg.setDirs()
+
+# Get test cases
+cfg.tests = parser.getTestCases()
+
+# Initialize print system
+Print = benchprint.initializePrint()
# Import the module
-mod = loadModule(cfg.modulename).Module(cfg.passargs)
-cfg.mod = mod
+cfg.module = loadModule(cfg.modulename).Module(cfg.moduleargs)
-# Write summary
+## Write summary
Print._level = 0
-Print(80*'=')
+Print(80 * '=')
Print("The following tests will be run:")
Print("-------------------------------")
Print()
@@ -126,25 +154,26 @@ for tname, ttest in cfg.tests.items():
if len(ttest['dependenv']) != 0:
Print(" - Dependencies emerge environment: " + \
- ' '.join([n+'="'+v+'"' for n,v in ttest['dependenv'].items()]))
+ ' '.join([n + '="' + v + '"' for n, v in ttest['dependenv'].items()]))
if len(ttest['emergeenv']) != 0:
Print(" - Emerge environment: " + \
- ' '.join([n+'="'+v+'"' for n,v in ttest['emergeenv'].items()]))
+ ' '.join([n + '="' + v + '"' for n, v in ttest['emergeenv'].items()]))
if len(ttest['compileenv']) != 0:
Print(" - Suite compile-time environment: " + \
- ' '.join([n+'="'+v+'"' for n,v in ttest['compileenv'].items()]))
+ ' '.join([n + '="' + v + '"' for n, v in ttest['compileenv'].items()]))
if len(ttest['runenv']) != 0:
Print(" - Suite run-time environment: " + \
- ' '.join([n+'="'+v+'"' for n,v in ttest['runenv'].items()]))
+ ' '.join([n + '="' + v + '"' for n, v in ttest['runenv'].items()]))
if len(ttest['skip']) != 0:
Print(" - Skip implementations: " + ' '.join(ttest['skip']))
if len(ttest['skipre']) != 0:
- Print(" - Skip implementations (regular expressions): " + ' '.join(ttest['skipre']))
+ Print(" - Skip implementations (regular expressions): " + \
+ ' '.join(ttest['skipre']))
if len(ttest['requires']) != 0:
Print(" - Pkg-config requirements substitutions:", '')
@@ -153,7 +182,7 @@ for tname, ttest in cfg.tests.items():
Print()
Print()
-Print(80*'=')
+Print(80 * '=')
Print()
Print("The script is located in the directory " + cfg.scriptdir)
Print("The script is run from the directory " + os.path.realpath('.'))
@@ -163,8 +192,8 @@ Print("The results will be available in the directory " + cfg.reportdir)
Print()
-# Main iteration
-for tn,(name,test) in enumerate(cfg.tests.items(),1):
+## Main iteration
+for tn, (name, test) in enumerate(cfg.tests.items(), 1):
Print._level = 0
Print("BEGIN TEST %i - %s" % (tn, name))
@@ -198,22 +227,22 @@ for tn,(name,test) in enumerate(cfg.tests.items(),1):
# Find implementations
impls = []
- for i in mod.getImplementations(test):
+ for i in cfg.module.getImplementations(test):
skip = False
-
+
for s in test['skip']:
if fnmatch(i, s):
skip = True
break
-
+
for s in test['skipre']:
if re.search(s, i) != None:
skip = True
break
-
+
if not skip:
impls.append(i)
-
+
test['implementations'] = impls
# Automatically add environment
@@ -227,7 +256,7 @@ for tn,(name,test) in enumerate(cfg.tests.items(),1):
# Run the test suite
Print("Testing " + impl)
Print.down()
- test['results'][impl] = mod.runTest(test, impl)
+ test['results'][impl] = cfg.module.runTest(test, impl)
Print.up()
# All implementations tested
@@ -235,7 +264,10 @@ for tn,(name,test) in enumerate(cfg.tests.items(),1):
print
+## End of execution
+
# Save the results
+import report
report.saveReport()
# Clean up the directories
@@ -251,12 +283,12 @@ exit(0)
Print._level = 0
Print()
# Print instructions
-for name,test in cfg.tests.items():
+for name, test in cfg.tests.items():
if not test['emergesuccess']:
continue
printstr = "Instructions for " + name + ":"
Print(printstr)
- Print(len(printstr)*'-')
+ Print(len(printstr) * '-')
Print.down()
Print("# PKGDIR=" + test['pkgdir'] + " emerge -K '=" + \
test['normalizedPackage'] + "'")
@@ -264,7 +296,7 @@ for name,test in cfg.tests.items():
for impl in test['implementations']:
Print("Implementation " + impl + ":")
Print.down()
- mod.instructionsFor(impl)
+ cfg.module.instructionsFor(impl)
Print.up()
except:
pass
diff --git a/numbench/report.py b/numbench/report.py
index 5f834db..e0de31a 100644
--- a/numbench/report.py
+++ b/numbench/report.py
@@ -42,26 +42,26 @@ class Plotter:
return
else:
self.plot = conf['type']
-
+
# Labels
self.xlabel = conf.has_key('xlabel') and conf['xlabel'] or ''
self.ylabel = conf.has_key('ylabel') and conf['ylabel'] or ''
-
+
# Initialize markers
markers = ('-', '--', 'v', '^', 'o', 's', 'p', 'h', '*', '+', 'x', 'D')
colors = ('k', 'r', 'g', 'b', 'c')
- self.linestyles = tuple([c+m for m in markers for c in colors])
+ self.linestyles = tuple([c + m for m in markers for c in colors])
self.curstyle = 0
-
+
# Open figure
- plt.figure(figsize=(12,9), dpi=300)
-
-
+ plt.figure(figsize=(12, 9), dpi=300)
+
+
def addPlot(self, x, y, label):
style = self.linestyles[self.curstyle]
- self.curstyle = (self.curstyle+1) % len(self.linestyles)
+ self.curstyle = (self.curstyle + 1) % len(self.linestyles)
self.plotf(x, y, style, label=label, hold=True)
-
+
def savePlot(self, fname):
plt.legend(loc='best')
plt.xlabel(self.xlabel)
@@ -69,7 +69,7 @@ class Plotter:
plt.grid(True)
plt.savefig(fname, format=cfg.imageformat, \
bbox_inches='tight', transparent=True)
-
+
def saveReport():
@@ -90,26 +90,26 @@ def saveReport():
htmlfname = pjoin(cfg.reportdir, 'index.html')
html = HTMLreport(htmlfname)
- for operation in cfg.mod.getTests():
-
+ for operation in cfg.module.getTests():
+
# Begin plot
- p = Plotter(cfg.mod.reportConf())
-
- for tid,test in cfg.tests.items():
+ p = Plotter(cfg.module.reportConf())
+
+ for tid, test in cfg.tests.items():
if test.has_key('implementations'):
for impl in test['implementations']:
-
+
implres = test['results'][impl]
if implres and implres.has_key(operation):
resultsFile = implres[operation]
- x,y = np.loadtxt(resultsFile, unpack=True)
- p.addPlot(x, y, tid+'/'+impl)
+ x, y = np.loadtxt(resultsFile, unpack=True)
+ p.addPlot(x, y, tid + '/' + impl)
- imgpath = pjoin('images', operation+'.'+cfg.imageformat)
+ imgpath = pjoin('images', operation + '.' + cfg.imageformat)
fname = pjoin(cfg.reportdir, imgpath)
p.savePlot(fname)
html.addFig(testdescr[operation], image=imgpath)
-
+
# Copy logs and input file
copytree(cfg.logdir, pjoin(cfg.reportdir, 'log'))
fcopy(cfg.inputfile, pjoin(cfg.reportdir, basename(cfg.inputfile)));
@@ -120,13 +120,13 @@ def saveReport():
# Initialize module
+# Import matplotlib and use 'Agg' as backend
try:
- if not locals().has_key('initialized'):
+ if 'initialized' not in locals():
initialized = True
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
- import numpy as np
with_images = True
except ImportError:
sys.stderr.write('Error: matplotlib and numpy are needed' + \
diff --git a/numbench/reports/html.py b/numbench/reports/html.py
index 227de57..5a45c35 100644
--- a/numbench/reports/html.py
+++ b/numbench/reports/html.py
@@ -22,8 +22,10 @@ from xml.sax.saxutils import escape as xmlescape
from .. import benchconfig as cfg
class ReportFile:
- def __init__(self, fname, title='Benchmarks report', \
- inputfile=pjoin(cfg.reportdir, basename(cfg.inputfile))):
+ def __init__(self, fname, title='Benchmarks report', inputfile=None):
+ if inputfile is None:
+ inputfile = pjoin(cfg.reportdir, basename(cfg.inputfile))
+
self.fname = fname
self.content = """
<html>
diff --git a/numbench/utils/benchutils.py b/numbench/utils/benchutils.py
index 1018d72..5a58e35 100644
--- a/numbench/utils/benchutils.py
+++ b/numbench/utils/benchutils.py
@@ -15,25 +15,25 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
-import os, sys, shutil, string, random
+import os, shutil, string, random
import subprocess as sp
__all__ = ['mkdir', 'tmpfile', 'run_cmd']
-def mkdir(dir):
- if not os.path.exists(dir):
- os.makedirs(dir)
+def mkdir(directory):
+ if not os.path.exists(directory):
+ os.makedirs(directory)
-def rmdir(dir):
- if os.path.isdir(dir):
- shutil.rmtree(dir, True)
+def rmdir(directory):
+ if os.path.isdir(directory):
+ shutil.rmtree(directory, True)
-def tmpfile(dir="/var/tmp"):
+def tmpfile(directory="/var/tmp"):
"""Returns the path of a free temporary file within the given directory."""
chars = string.letters + string.digits
while True:
- fname = os.path.join(dir, random.sample(chars, 10))
+ fname = os.path.join(directory, random.sample(chars, 10))
if not os.path.exists(fname):
return fname
diff --git a/numbench/utils/envread.py b/numbench/utils/envread.py
index 126f225..0d7d756 100644
--- a/numbench/utils/envread.py
+++ b/numbench/utils/envread.py
@@ -17,7 +17,7 @@
#
import os, shlex
from os.path import isfile, join as pjoin
-from ..benchconfig import libdir
+from .. import benchconfig as cfg
def transformPaths(root, value):
paths = value.split(':')
@@ -33,7 +33,7 @@ def transformPaths(root, value):
def envread(test):
# Set default paths
path = pjoin(test['root'], 'bin') + ':' + pjoin(test['root'], 'usr/bin')
- libpath = pjoin(test['root'], libdir)
+ libpath = pjoin(test['root'], cfg.libdir)
addenv = dict( PATH=path, LIBRARY_PATH=libpath, LD_LIBRARY_PATH=libpath )
# Merge environment
diff --git a/numbench/utils/portageutils.py b/numbench/utils/portageutils.py
index 6fa864a..8775d42 100644
--- a/numbench/utils/portageutils.py
+++ b/numbench/utils/portageutils.py
@@ -17,10 +17,12 @@
#
import commands as cmd
import subprocess as sp
-import os, portage, shlex
+import os, shlex
from os.path import join as pjoin, dirname
import benchutils as bu
+from portage import catpkgsplit as cps #@UnresolvedImport
+
class InstallException(Exception):
def __init__(self, package, command, logfile):
self.package = package
@@ -55,7 +57,7 @@ def _getEnv(root='/', envAdds={}):
denv['INCLUDE_PATH'] += ':' + os.environ['INCLUDE_PATH']
# Adds
- for k,v in envAdds.items():
+ for k, v in envAdds.items():
denv[k] = v
return denv
@@ -67,13 +69,13 @@ def availablePackages(pattern):
No test for keywords or mask is performed. The function just returns
every matching pattern in the portage tree and installed overlays.
"""
- return [portage.catpkgsplit(l) \
+ return [cps(l)
for l in cmd.getoutput('equery -q list -po ' + pattern).split()]
def normalize_cpv(cpv):
if type(cpv) == type(''):
try:
- cpv_ = portage.catpkgsplit(cpv)
+ cpv_ = cps(cpv)
cpv_[-1]
cpv = cpv_
except:
@@ -86,16 +88,16 @@ def normalize_cpv(cpv):
def getDependencies(package, env={}, split=False):
pkg = normalize_cpv(package)
- cmd = ['emerge', '--ignore-default-opts', '='+pkg, '-poq']
+ cmd = ['emerge', '--ignore-default-opts', '=' + pkg, '-poq']
proc = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.PIPE, env=env)
- output = proc.communicate()[0]
+ output = proc.communicate()[0]
if proc.returncode != 0:
return []
lines = output.strip().split('\n')
if not lines[0]:
return []
if split:
- return [portage.catpkgsplit(shlex.split(l.strip())[-1]) for l in lines]
+ return [cps(shlex.split(l.strip())[-1]) for l in lines]
else:
return [shlex.split(l.strip())[-1] for l in lines]
@@ -107,7 +109,7 @@ def installDependencies(test):
# Retrieve dependencies
deps = getDependencies(test['package'], denv, False)
- for i,d in enumerate(deps):
+ for i, d in enumerate(deps):
logfile = pjoin(test['logdir'], 'emergedep_%i.log' % i)
installPackage(test, package=d, env=test['dependenv'], logfile=logfile)
@@ -160,13 +162,13 @@ def installPackage(test, package=None, env=None, logfile=None):
# In case of error, print the whole emerge command
raise InstallException(pkg, ' '.join(cmd), logfile)
- fout.write('\n\n' + 80*'#' + '\n\n')
+ fout.write('\n\n' + 80 * '#' + '\n\n')
# Unpack package onto root
- archive = pjoin(test['pkgdir'], pkg+'.tbz2')
+ archive = pjoin(test['pkgdir'], pkg + '.tbz2')
bu.mkdir(test['root'])
tarcmd = ['tar', 'xjvf', archive, '-C', test['root']]
- fout.write(' '.join(tarcmd) + '\n' + 80*'-' + '\n')
+ fout.write(' '.join(tarcmd) + '\n' + 80 * '-' + '\n')
p = sp.Popen(tarcmd, stdout=fout, stderr=sp.STDOUT)
p.wait()
if p.returncode != 0:
@@ -175,9 +177,3 @@ def installPackage(test, package=None, env=None, logfile=None):
# Close, return
fout.close()
-
-if __name__ == '__main__':
- # Just a test
- from pprint import pprint
-
- pprint(get_dependencies('sci-libs/blas-reference-3.3.1-r1'))
diff --git a/numbench/xmlinput.py b/numbench/xmlinput.py
new file mode 100644
index 0000000..62f8289
--- /dev/null
+++ b/numbench/xmlinput.py
@@ -0,0 +1,170 @@
+import xml.dom.minidom
+import sys, os, portage, types, shlex, subprocess as sp
+from os.path import join as pjoin
+
+import benchconfig as cfg
+from utils import portageutils as pu
+
+class Parser:
+ def __init__(self, fname):
+ self._dom = xml.dom.minidom.parse(fname)
+
+ def getModuleName(self):
+ opTag = self._dom.getElementsByTagName('operations')[0]
+ return opTag.getAttribute('module')
+
+ def getModuleArguments(self):
+ opTag = self._dom.getElementsByTagName('operations')[0]
+ return shlex.split(opTag.firstChild.data)
+
+ def getTestCases(self):
+ testNodes = self._dom.getElementsByTagName('case')
+
+ tests = {}
+
+ for t in testNodes:
+ tid = t.getAttribute('id')
+
+ # Get description
+ descr = None
+ if len(t.getElementsByTagName('descr')) != 0:
+ descr = t.getElementsByTagName('descr')[0].firstChild.data
+
+ # Get package
+ pkg = portage.catpkgsplit(#@UndefinedVariable
+ t.getElementsByTagName('pkg')[0].firstChild.data)
+ normPkg = pu.normalize_cpv(pkg)
+
+ # Skip implementations
+ skip = []
+ skipre = []
+ for s in t.getElementsByTagName('skip'):
+ if not s.hasAttribute('type') or s.getAttribute('type') == 'glob':
+ skip.append(s.firstChild.data)
+ elif s.getAttribute('type') == 'regexp':
+ skipre.append(s.firstChild.data)
+ else:
+ sys.stderr.write('Error in configuration file: skip type ' \
+ + s.getAttribute('type') + ' not supported')
+
+ # Requirements
+ requires = {}
+ for i in t.getElementsByTagName('required'):
+ requires[i.getAttribute('name').strip()] = i.firstChild.data.strip()
+
+ # Environments
+ dependenv = self._getEnvFromNode(t, 'dependenv')
+ emergeenv = self._getEnvFromNode(t, 'emergeenv')
+ compileenv = self._getEnvFromNode(t, 'compileenv')
+ runenv = self._getEnvFromNode(t, 'runenv')
+
+ # Adjust PATH
+ if compileenv.has_key('PATH'):
+ compileenv['PATH'] += ':' + os.environ['PATH']
+ else:
+ compileenv['PATH'] = os.environ['PATH']
+
+ if runenv.has_key('PATH'):
+ runenv['PATH'] += ':' + os.environ['PATH']
+ else:
+ runenv['PATH'] = os.environ['PATH']
+
+ # Build test dictionary
+ tests[tid] = dict(
+ descr=descr,
+ package=pkg,
+ normalizedPackage=normPkg,
+ skip=skip,
+ skipre=skipre,
+ requires=requires,
+
+ dependenv=dependenv,
+ emergeenv=emergeenv,
+ compileenv=compileenv,
+ runenv=runenv,
+
+ pkgdir=pjoin(cfg.pkgsdir, tid),
+ archive=pjoin(cfg.pkgsdir, tid, normPkg + '.tbz2'),
+ root=pjoin(cfg.rootsdir, tid),
+ testdir=pjoin(cfg.testsdir, tid),
+ logdir=pjoin(cfg.logdir, tid)
+ )
+
+ return tests
+
+ @staticmethod
+ def _readFile(fs):
+ result = {}
+
+ # If fs is a filename, open it
+ if type(fs) != types.FileType:
+ fs = file(pjoin(cfg.curdir, fs))
+
+ # Read line by line
+ for l in fs.readlines():
+ try:
+ k, v = l.split('=', 1)
+ result[k.strip()] = v.strip()
+ except:
+ pass
+
+ return result
+
+ @classmethod
+ def _readScript(cls, fname):
+ fname = pjoin(cfg.curdir, fname)
+
+ # Execute script with void environment
+ proc = sp.Popen('. ' + fname + ' &> /dev/null; env', shell=True,
+ stdout=sp.PIPE, env={})
+ result = cls._readFile(proc.stdout)
+
+ # Remove useless variables
+ for k in ('SHLVL', 'PWD', '_'):
+ if result.has_key(k):
+ del result[k]
+ return result
+
+ @classmethod
+ def _getEnvFromNode(cls, node, envName):
+ envs = node.getElementsByTagName(envName)
+
+ # Check number of envs
+ if len(envs) > 1:
+ errstr = "Error: no more than one " + envName + " element is allowed!"
+ raise Exception(errstr)
+ elif len(envs) < 1:
+ return {}
+
+ e = envs[0]
+
+ # Check attribute "append"
+ if (e.attributes.has_key('append')):
+ append = e.attributes['append'].value == '1'
+ else:
+ append = False
+
+ if append:
+ env = os.environ
+ else:
+ env = {}
+
+ # Check attribute script
+ # the script is run with a void environment
+ if (e.attributes.has_key('script')):
+ for k, v in cls._readScript(e.getAttribute('script')).items():
+ env[k] = v
+
+ # Check attribute file
+ # the file must contain lines with key=value pairs (each line one pair)
+ if (e.attributes.has_key('file')):
+ for k, v in cls._readFile(e.getAttribute('file')).items():
+ env[k] = v
+
+ # Get Variables
+ for v in e.getElementsByTagName('var'):
+ envname = v.getAttribute('name')
+ envvalue = v.firstChild.data
+ env[envname] = envvalue
+
+ return env