summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Arteaga <andyspiros@gmail.com>2012-02-15 02:13:15 +0000
committerAndrea Arteaga <andyspiros@gmail.com>2012-02-15 02:13:15 +0000
commit877a2a0a7e9441e6d8e3f34df83a86032af54098 (patch)
tree8f08d1f4479c9dd2c55022405032afb2a0a02ef9 /numbench/utils
parentRemoved buggy load printer thread. (diff)
downloadauto-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__.py0
-rw-r--r--numbench/utils/alternatives.py60
-rw-r--r--numbench/utils/benchpkgconfig.py70
-rw-r--r--numbench/utils/btl.py240
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])