diff options
author | Andrea Arteaga <andyspiros@gmail.com> | 2012-02-15 02:13:15 +0000 |
---|---|---|
committer | Andrea Arteaga <andyspiros@gmail.com> | 2012-02-15 02:13:15 +0000 |
commit | 877a2a0a7e9441e6d8e3f34df83a86032af54098 (patch) | |
tree | 8f08d1f4479c9dd2c55022405032afb2a0a02ef9 /numbench/utils | |
parent | Removed buggy load printer thread. (diff) | |
download | auto-numerical-bench-877a2a0a7e9441e6d8e3f34df83a86032af54098.tar.gz auto-numerical-bench-877a2a0a7e9441e6d8e3f34df83a86032af54098.tar.bz2 auto-numerical-bench-877a2a0a7e9441e6d8e3f34df83a86032af54098.zip |
Rewritten code... New XML parser, better modules. Not completely tested!
Diffstat (limited to 'numbench/utils')
-rw-r--r-- | numbench/utils/__init__.py | 0 | ||||
-rw-r--r-- | numbench/utils/alternatives.py | 60 | ||||
-rw-r--r-- | numbench/utils/benchpkgconfig.py | 70 | ||||
-rw-r--r-- | numbench/utils/btl.py | 240 |
4 files changed, 370 insertions, 0 deletions
diff --git a/numbench/utils/__init__.py b/numbench/utils/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/numbench/utils/__init__.py diff --git a/numbench/utils/alternatives.py b/numbench/utils/alternatives.py new file mode 100644 index 0000000..d69937b --- /dev/null +++ b/numbench/utils/alternatives.py @@ -0,0 +1,60 @@ +#===================================================== +# Copyright (C) 2012 Andrea Arteaga <andyspiros@gmail.com> +#===================================================== +# +# 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; either version 2 +# of the License, or (at your option) any later version. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +import subprocess as sp +import benchpkgconfig as pc +import shlex + +def getImplementations(root, libname): + cmd = ['eselect', '--no-color', '--brief', libname, 'list'] + env = dict(ROOT=root) + output = sp.Popen(cmd, env=env, stdout=sp.PIPE).communicate()[0].strip() + if '(none found)' in output: + return [] + else: + return [i.split()[0] for i in output.split('\n')] + + +def getFlags(test, libname, impl): + root = test['root'] + + # 1. Run without requires + pfile = pc.getFile(libname, impl, root) + flags = pc.run(pfile, root, False) + + # TODO: add log +# logfile = file(pjoin(self.logdir, 'pkg-config.log'), 'w') +# print >> logfile, "File:", pfile +# print >> logfile, "Result:", flags + + # 2. Get requires + requires = pc.requires(pfile) + # TODO: add log print >> logfile, "Requires:", requires + + # 3. Substitute requires and add flags + if test.has_key('requires'): + for r in requires: + if r in test['requires'].keys(): + pfile = pc.getFile(r, test['requires'][r]) + flags += ' ' + pc.run(pfile) + else: + flags += ' ' + pc.run(r) + # TODO: add log +# print >> logfile, "Third run:", flags +# logfile.close() + + return shlex.split(flags)
\ No newline at end of file diff --git a/numbench/utils/benchpkgconfig.py b/numbench/utils/benchpkgconfig.py new file mode 100644 index 0000000..2ecc10a --- /dev/null +++ b/numbench/utils/benchpkgconfig.py @@ -0,0 +1,70 @@ +#===================================================== +# Copyright (C) 2011 Andrea Arteaga <andyspiros@gmail.com> +#===================================================== +# +# 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; either version 2 +# of the License, or (at your option) any later version. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +import os, types +from os.path import join as pjoin, basename, dirname +import subprocess as sp + +from .. import benchconfig as cfg + +def getFile(pfile, impl, roots='/'): + if pfile[-3:] != '.pc': + fname = pfile + '.pc' + else: + fname = pfile + + libdir = cfg.libdir + while libdir[0] == '/': + libdir = libdir[1:] + + # Check alternatives + if type(roots) in types.StringTypes: + roots = (roots, ) + pkgcfgpath = ':'.join([pjoin(r,'etc/env.d/alternatives', pfile, impl, \ + libdir, 'pkgconfig', fname) for r in roots]) + + if os.path.exists(pkgcfgpath): + return pkgcfgpath + else: + raise Exception('pkg-config file "' + pfile + '" not found', pkgcfgpath) + +def requires(fname): + env = {'PKG_CONFIG_PATH' : dirname(fname)} + cmd = ['pkg-config', '--print-requires', basename(fname)[:-3]] + proc = sp.Popen(cmd, env=env, stdout=sp.PIPE) + return proc.communicate()[0].split() + + +def run(fname, root='/', requires=True): + if not requires: + lines = file(fname, 'r').readlines() + newlines = [l for l in lines if l[:10] != 'Requires: '] + file(fname, 'w').writelines(newlines) + + bname = basename(fname) + if bname[-3:] == '.pc': + bname = bname[:-3] + + env = {'PKG_CONFIG_PATH' : dirname(fname), 'PKG_CONFIG_SYSROOT_DIR' : root} + cmd = ['pkg-config', '--libs', '--cflags', bname] + proc = sp.Popen(cmd, env=env, stdout=sp.PIPE) + out = proc.communicate()[0].strip() + + if not requires: + file(fname, 'w').writelines(lines) + + return out
\ No newline at end of file diff --git a/numbench/utils/btl.py b/numbench/utils/btl.py new file mode 100644 index 0000000..edb3a18 --- /dev/null +++ b/numbench/utils/btl.py @@ -0,0 +1,240 @@ +#===================================================== +# Copyright (C) 2012 Andrea Arteaga <andyspiros@gmail.com> +#===================================================== +# +# 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; either version 2 +# of the License, or (at your option) any later version. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +from .. import benchchildren, benchutils as bu, benchconfig as cfg +from ..benchprint import Print + +from os.path import join as pjoin, dirname +import shlex, subprocess as sp + +# BTL global flags +btlincludes = ('actions','generic_bench','generic_bench/utils','libs/STL') +btllibraries = ('rt',) +btldefines = ('NDEBUG',) + + + +def compileTest(test, btlconfig): + + # Include directories + includes = [pjoin(cfg.btldir, i) for i in btlincludes] + if btlconfig.has_key('btlincludes'): + includes += [pjoin(cfg.btldir, i) for i in btlconfig['btlincludes']] + if btlconfig.has_key('includes'): + includes += btlconfig['includes'] + + # Linked libraries + libraries = list(btllibraries) + if btlconfig.has_key('libraries'): + libraries += btlconfig['libraries'] + + # Library directories + libdirs = [pjoin(test['root'], cfg.libdir)] + if btlconfig.has_key('libdirs'): + libdirs += btlconfig['libdirs'] + + # Defined preprocessor macros + defines = list(btldefines) + if btlconfig.has_key('defines'): + defines += btlconfig['defines'] + + # Other flags + flags = [] + + # Interpret flags + interpret = shlex.split(bu.run_cmd(['portageq', 'envvar', 'CXXFLAGS'])) + if btlconfig.has_key('flags'): + interpret += btlconfig['flags'] + for flag in interpret: + flag = flag.strip() + if flag[:2] == '-I': + includes.append(flag[2:]) + elif flag[:2] == '-l': + libraries.append(flag[2:]) + elif flag[:2] == '-L': + libdirs.append(flag[2:]) + else: + flags.append(flag) + del interpret + + + # Set compile-time environment + compileenv = test['compileenv'].copy() + + if compileenv.has_key('INCLUDE_PATH'): + compileenv['INCLUDE_PATH'] += ':' + ':'.join(includes) + else: + compileenv['INCLUDE_PATH'] = ':'.join(includes) + + libenv = ':'.join(libdirs) + if compileenv.has_key('LIBRARY_PATH'): + compileenv['LIBRARY_PATH'] += ':' + libenv + else: + compileenv['LIBRARY_PATH'] = libenv + + if compileenv.has_key('LD_LIBRARY_PATH'): + compileenv['LD_LIBRARY_PATH'] += ':' + libenv + else: + compileenv['LD_LIBRARY_PATH'] = libenv + + pathenv = ':'.join([pjoin(test['root'], l) for l in ('bin', 'usr/bin')]) + if compileenv.has_key('PATH'): + compileenv['PATH'] += pathenv + else: + compileenv['PATH'] = pathenv + + # Set run-time environment + runenv = test['runenv'].copy() + + if runenv.has_key('LD_LIBRARY_PATH'): + runenv['LD_LIBRARY_PATH'] += ':' + libenv + else: + runenv['LD_LIBRARY_PATH'] = libenv + + pathenv = ':'.join([pjoin(test['root'], l) for l in ('bin', 'usr/bin')]) + if runenv.has_key('PATH'): + runenv['PATH'] += pathenv + else: + runenv['PATH'] = pathenv + + btlconfig['runenv'] = runenv + + + # Set C++ compiler + cxx = '/usr/bin/g++' + + portageq_cxx = bu.run_cmd(['portageq', 'envvar', 'CXX']) + if portageq_cxx.strip() != "": + cxx = portageq_cxx + del portageq_cxx + + if btlconfig.has_key('CXX'): + cxx = btlconfig['CXX'] + + if compileenv.has_key('CXX'): + cxx = compileenv['CXX'] + + + # Form command-line arguments + args = [cxx, pjoin(cfg.btldir, btlconfig['source']), '-o', btlconfig['exe']] + args += ['-I'+I for I in includes] + args += ['-l'+l for l in libraries] + args += ['-L'+L for L in libdirs] + args += ['-D'+D for D in defines] + args += flags + + # Open logfile and write environment + bu.mkdir(btlconfig['logdir']) + logfile = pjoin(btlconfig['logdir'], "btlCompile.log") + logfs = file(logfile, 'w') + logfs.write('\n'.join([n+'='+v for n,v in compileenv.items()])) + logfs.write(3*'\n' + ' '.join(args) + 3*'\n') + logfs.flush() + + # Execute compilation + bu.mkdir(dirname(btlconfig['exe'])) + proc = sp.Popen(args, stdout=logfs, stderr=sp.STDOUT, env=compileenv) + proc.wait() + logfs.flush() + retcode = proc.returncode + if retcode == 0: + logfs.write("\n\n<<< Compilation terminated successfully >>>") + else: + logfs.write("\n\n<<< Compilation failed >>>") + + # Close, return + logfs.close() + return retcode + + +def runTest(test, btlconfig): + runenv = btlconfig['runenv'] + + # Check linking + logfs = file(pjoin(btlconfig['logdir'], 'btlLinking.log'), 'w') + sp.Popen(['ldd', '-v', btlconfig['exe']], stdout=logfs, env=runenv).wait() + logfs.close() + + + # Prepare arguments + args = (btlconfig['exe'],) + tuple(btlconfig['tests']) + if btlconfig.has_key('preargs'): + args = btlconfig['preargs'] + args + if btlconfig.has_key('postargs'): + args = args + btlconfig['postargs'] + + # Open log + logfs = file(pjoin(btlconfig['logdir'], "btlRun.log"), 'w') + logfs.write('\n'.join([n+'='+v for n,v in runenv.items()])) + logfs.write(3*'\n' + ' '.join(args) + 3*'\n') + logfs.flush() + + # Open pipe + proc = sp.Popen(args, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE, \ + env=runenv, cwd=btlconfig['testdir']) + benchchildren.append(proc) + + result = {} + + # Interpret output + Print('Begin execution') + while True: + # Each operation test begins with a line on stderr + errline = proc.stderr.readline() + if not errline: + break + logfs.write(errline) + + resfile = errline.split()[-1] + operation = resfile.split('_', 1)[-1].rsplit('_', 1)[0] + result[operation] = resfile + Print(operation + " -> " + resfile) + + + # Many different sizes for each operation test + Print.down() + cur = 0 + tot = 1 + while cur != tot: + outline = proc.stdout.readline() + # If the line is void, something gone wrong + if not outline: + Print.up() + Print('Execution error') + return 1 + logfs.write(outline) + logfs.flush() + + # Interpret line + outline = outline.strip() + (cur, tot) = shlex.split(outline)[-1][1:-1].split('/') + cur = int(cur); tot = int(tot) + Print(outline) + + + Print.up() + proc.wait() + Print("Execution finished with return code " + str(proc.returncode)) + + # Close, return + logfs.close() + return proc.returncode, result + + + +def selectTests(availableTests, args): + return tuple([i for i in availableTests if i in args]) |