summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Arteaga <andyspiros@gmail.com>2012-08-06 00:56:55 +0200
committerAndrea Arteaga <andyspiros@gmail.com>2012-08-06 01:02:22 +0200
commitf4ebe8fa598045dae33a1dc160d231c193f59004 (patch)
tree15b02da22026d27e72bf094fc733b1a4d341f72d
parentCleaned modules. (diff)
downloadauto-numerical-bench-f4ebe8fa598045dae33a1dc160d231c193f59004.tar.gz
auto-numerical-bench-f4ebe8fa598045dae33a1dc160d231c193f59004.tar.bz2
auto-numerical-bench-f4ebe8fa598045dae33a1dc160d231c193f59004.zip
Input parser, initializations, code cleanup.0.2_beta4
The old parser has been removed. Now only xml input is supported. xmlinput now has a class Parser. Module name and arguments are now present in the configuration file. Informations can be retrived separately from the file. benchconfig initialization is now splitted in functions that are called from within main.py. the same happens in benchprint. benchconfig now explicitly defines all the variables. In general, some clean up has been done and some warnings have been suppressed.
-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