From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1Qdqrp-0006GV-RV for garchives@archives.gentoo.org; Mon, 04 Jul 2011 21:39:47 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 893B721C0E1; Mon, 4 Jul 2011 21:39:01 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id 17B8921C0E1 for ; Mon, 4 Jul 2011 21:39:00 +0000 (UTC) Received: from pelican.gentoo.org (unknown [66.219.59.40]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 6E2AF1B4006 for ; Mon, 4 Jul 2011 21:39:00 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by pelican.gentoo.org (Postfix) with ESMTP id 9B22180040 for ; Mon, 4 Jul 2011 21:38:59 +0000 (UTC) From: "Andrea Arteaga" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Andrea Arteaga" Message-ID: <30b1b4ec2c495adaab4a7c33656ce994a661b4ea.spiros@gentoo> Subject: [gentoo-commits] proj/auto-numerical-bench:master commit in: app-benchmarks/autobench/files/python/ X-VCS-Repository: proj/auto-numerical-bench X-VCS-Files: app-benchmarks/autobench/files/python/basemodule.py app-benchmarks/autobench/files/python/benchconfig.py app-benchmarks/autobench/files/python/benchprint.py app-benchmarks/autobench/files/python/benchutils.py app-benchmarks/autobench/files/python/blas_accuracy.py app-benchmarks/autobench/files/python/blasbase.py app-benchmarks/autobench/files/python/btlbase.py app-benchmarks/autobench/files/python/lapack.py app-benchmarks/autobench/files/python/main.py X-VCS-Directories: app-benchmarks/autobench/files/python/ X-VCS-Committer: spiros X-VCS-Committer-Name: Andrea Arteaga X-VCS-Revision: 30b1b4ec2c495adaab4a7c33656ce994a661b4ea Date: Mon, 4 Jul 2011 21:38:59 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: edf75e16072ce421db6f9b57e44b6018 commit: 30b1b4ec2c495adaab4a7c33656ce994a661b4ea Author: spiros gmail com> AuthorDate: Mon Jul 4 21:38:32 2011 +0000 Commit: Andrea Arteaga gmail com> CommitDate: Mon Jul 4 21:38:32 2011 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/auto-numerica= l-bench.git;a=3Dcommit;h=3D30b1b4ec Introduced benchconfig: configuration module; benchutils and benchprint: common utilities. New classes *Test: facilities splitted between Modules and Tests. Unified paths, logs, output. --- .../autobench/files/python/basemodule.py | 250 +++++++++++---= ------ .../autobench/files/python/benchconfig.py | 75 ++++++ .../autobench/files/python/benchprint.py | 28 +++ .../autobench/files/python/benchutils.py | 8 + .../autobench/files/python/blas_accuracy.py | 138 ++++++++--- app-benchmarks/autobench/files/python/blasbase.py | 10 +- app-benchmarks/autobench/files/python/btlbase.py | 225 ++++++++------= ---- app-benchmarks/autobench/files/python/lapack.py | 13 +- app-benchmarks/autobench/files/python/main.py | 103 ++------- 9 files changed, 494 insertions(+), 356 deletions(-) diff --git a/app-benchmarks/autobench/files/python/basemodule.py b/app-be= nchmarks/autobench/files/python/basemodule.py index 5a35cc7..d84d27b 100644 --- a/app-benchmarks/autobench/files/python/basemodule.py +++ b/app-benchmarks/autobench/files/python/basemodule.py @@ -1,8 +1,12 @@ from os.path import join as pjoin import subprocess as sp import shlex, os + +import benchconfig as cfg from htmlreport import HTMLreport import basemodule +from benchutils import * +from benchprint import Print =20 try: import matplotlib.pyplot as plt @@ -14,12 +18,9 @@ except ImportError: sys.stderr.write('Continue anyway.\n\n') =20 with_images =3D False =20 -run_cmd =3D lambda c : sp.Popen(c, stdout=3Dsp.PIPE).communicate()[0] =20 class BaseModule: - def __init__(self, Print, libdir, args): - self.Print =3D Print - self.libdir =3D libdir + def __init__(self, args): self.summary =3D False self.summary_only =3D False =20 @@ -37,119 +38,26 @@ class BaseModule: passargs +=3D [i] =20 self._parse_args(passargs) - =20 - # Alternatives-2 version with pkg-config - def _get_flags(self, root, impl, libdir): - while libdir[0] =3D=3D '/': - libdir =3D libdir[1:] - # Retrieve pkgconfig settings and map the directories to the new= root - path =3D pjoin(root, "etc/env.d/alternatives", \ - self.libname,impl,libdir, "pkgconfig") - cmd =3D ['pkg-config', '--libs', '--cflags', self.libname] - env =3D {'PKG_CONFIG_PATH':path} - pkgconf =3D sp.Popen(cmd, stdout=3Dsp.PIPE, env=3Denv).communica= te()[0] - pkgconf =3D pkgconf.replace('-L/', '-L'+root+'/') - pkgconf =3D pkgconf.replace('-I/', '-I'+root+'/') - return shlex.split(pkgconf) =20 # Alternatives-2 version + =20 def get_impls(self, root): output =3D sp.Popen( ['eselect', '--no-color', '--brief', self.libname, 'list'], env=3D{'ROOT' : root}, stdout=3Dsp.PIPE).communicate()[0] return output.strip().split('\n') - =20 - # Base version - def _generateResults(self, files): - return dict(zip(self.tests, files)) - =20 - def run_test(self, root, impl, testdir, env, logdir): - # Convenient renames and definition of report files - Print =3D self.Print - name =3D self.libname - files =3D [pjoin(testdir,f) for f in self.files] - if self.libdir[0] =3D=3D '/': - libdir =3D root+self.libdir - else: - libdir =3D pjoin(root, self.libdir) - =20 - # Create dir. If all results already exist use them and do not p= erform - # the tests, otherwise remove every old results. - runtests =3D False - if os.path.exists(testdir): - runtests =3D not all([os.path.exists(i) for i in files]) - else: - os.makedirs(testdir) - runtests =3D True - =20 - if not runtests: - Print("Not testing: results exist") - return self._generateResults(files) - =20 - for i in files: - if os.path.exists(i): os.remove(i) - =20 - # Prepare the environment - if env.has_key('LIBRARY_PATH'): - env['LIBRARY_PATH'] =3D libdir + ":" + env['LIBRARY_PATH'] - else: - env['LIBRARY_PATH'] =3D libdir - =20 - if env.has_key('INCLUDE_PATH'): - env['INCLUDE_PATH'] =3D \ - pjoin(root, "usr/include") + ":" + env['INCLUDE_PATH'] - else: - env['INCLUDE_PATH'] =3D pjoin(root, "usr/include") - =20 - if env.has_key('LD_LIBRARY_PATH'): - env['LD_LIBRARY_PATH'] =3D \ - libdir + ":" + env['LD_LIBRARY_PATH'] - else: - env['LD_LIBRARY_PATH'] =3D libdir - =20 - # Backup the environment - oldenv =3D {} - for k in env.keys(): - oldenv[k] =3D \ - (os.environ.has_key(k) and (os.environ[k],) or (None,))[0] - =20 - # Set the new environment - for k,v in env.items(): - os.environ[k] =3D v - =20 - # Compile test suite - logfile =3D os.path.join(logdir, name+"_comp.log") - returncode, exe =3D self._compileTest(logfile=3Dlogfile, testdir= =3Dtestdir, \ - root=3Droot, impl=3Dimpl, libdir=3Dlibdir) - if returncode !=3D 0: - Print("Compilation failed") - Print("See log: " + logfile) - return - Print("Compilation successful") - =20 - # Run test - logfile =3D pjoin(logdir, name+"_run.log") - retcode =3D self._executeTest(logfile=3Dlogfile, exe=3Dexe, test= dir=3Dtestdir) - if returncode !=3D 0: - Print("Test failed") - Print("See log: " + logfile) - return - Print("Test successful") - =20 - # Restore the old environment - for k in env.keys(): - if oldenv[k] !=3D None: - os.environ[k] =3D oldenv[k] - elif os.environ.has_key(k): - del os.environ[k] - =20 - # Return - return self._generateResults(files) - =20 + =20 + def getTest(self, root, impl, testdir, logdir): + TestClass =3D self._testClass() + t =3D TestClass(root, impl, testdir, logdir) + t.libname =3D self.libname + t.tests =3D self.tests + t.files =3D self.files + return t =20 - def save_results(self, results, figdir, plottype=3D'plot'): + def save_results(self, results, plottype=3D'plot'): if not with_images: - self.Print("Report generation skipped - missing libraries") + Print("Report generation skipped - missing libraries") return =20 if plottype =3D=3D 'plot': plotf =3D plt.plot @@ -165,11 +73,13 @@ class BaseModule: newresults[test] =3D {} for nameimpl in results: nameimplstr =3D pjoin(*nameimpl) + if results[nameimpl] =3D=3D None: + continue resdat =3D results[nameimpl][test] newresults[test][nameimplstr] =3D resdat =20 # Begin the HTML report - htmlfname =3D pjoin(figdir, 'index.html') + htmlfname =3D pjoin(cfg.reportdir, 'index.html') html =3D HTMLreport(htmlfname) =20 # Generate summary - a single image with all plots @@ -185,10 +95,10 @@ class BaseModule: plotf(x,y, label=3Dimpl, hold=3DTrue) plt.legend(loc=3D'best') plt.grid(True) - fname =3D pjoin(figdir, 'summary.png') + fname =3D pjoin(cfg.reportdir, 'summary.png') plt.savefig(fname, format=3D'png') html.addFig("Summary", image=3Dos.path.basename(fname), widt= h=3D'95%') - self.Print('Summary figure saved: ' + fname) + Print('Summary figure saved: ' + fname) =20 # Generate plots if not self.summary_only: @@ -199,9 +109,123 @@ class BaseModule: plotf(x,y, label=3Dimpl, hold=3DTrue) plt.legend(loc=3D'best') plt.grid(True) - fname =3D pjoin(figdir, test+".png") + fname =3D pjoin(cfg.reportdir, test+".png") plt.savefig(fname, format=3D'png') html.addFig(test, image=3Dos.path.basename(fname)) - self.Print('Figure ' + fname + ' saved') + Print('Figure ' + fname + ' saved') =20 html.close() + Print('HTML report generated: ' + htmlfname) + +class CompilationError(Exception): + def __init__(self, logfile): + self.logfile =3D logfile + + +class BaseTest: + libname =3D None + tests =3D None + files =3D None + =20 + def __init__(self, root, impl, testdir, logdir): + self.root =3D root + self.impl =3D impl + self.testdir =3D testdir + self.logdir =3D pjoin(logdir, impl) + self.compileenv =3D {} + self.runenv =3D {} + =20 + mkdir(self.logdir) + =20 + self.libdir =3D cfg.libdir + while self.libdir[0] =3D=3D '/': + self.libdir =3D self.libdir[1:] + self.libdir =3D pjoin(self.root, self.libdir) + =20 + # Base version + def _generateResults(self): + return dict(zip(self.tests, self.files)) + =20 + # Alternatives-2 version with pkg-config + def _get_flags(self): + libdir =3D cfg.libdir + while libdir[0] =3D=3D '/': + libdir =3D libdir[1:] + =20 + # Retrieve pkgconfig settings and map the directories to the new= root + path =3D pjoin(self.root, "etc/env.d/alternatives", \ + self.libname, self.impl, libdir, "pkgconfig") + cmd =3D ['pkg-config', '--libs', '--cflags', self.libname] + env =3D { + 'PKG_CONFIG_PATH' : path, + 'PKG_CONFIG_LIBDIR' : '', + 'PKG_CONFIG_SYSROOT_DIR' : self.root + } + proc =3D sp.Popen(cmd, stdout=3Dsp.PIPE, stderr=3Dsp.STDOUT, env= =3Denv) + pkgconf =3D proc.communicate()[0] + =20 + # Write logfile + logfname =3D pjoin(self.logdir, 'pkgconfig.log') + logfile =3D file(logfname, 'w') + logfile.write('PKG_CONFIG_PATH=3D'+path + '\n') + logfile.write('PKG_CONFIG_LIBDIR=3D""' + '\n') + logfile.write('PKG_CONFIG_SYSROOT_DIR=3D'+self.root + '\n') + logfile.write(' '.join(cmd) + '\n') + logfile.write(80*'-' + '\n') + logfile.write(pkgconf) + logfile.close() + =20 + if proc.returncode !=3D 0: + raise CompilationError(logfname) + =20 + return shlex.split(pkgconf) + =20 + def run_test(self): + # Convenient renames and definition of report files + name =3D self.libname + root =3D self.root + testdir =3D self.testdir + self.files =3D [pjoin(testdir,f) for f in self.files] + env =3D {} # TODO: remove this + if cfg.libdir[0] =3D=3D '/': + libdir =3D root+cfg.libdir + else: + libdir =3D pjoin(root, cfg.libdir) + =20 + # Create dir. If all results already exist use them and do not p= erform + # the tests, otherwise remove every old results. + runtests =3D False + if os.path.exists(testdir): + runtests =3D not all([os.path.exists(i) for i in self.files]= ) + else: + os.makedirs(testdir) + runtests =3D True + if not runtests: + Print("Not testing: results exist") + return self._generateResults() + for i in self.files: + if os.path.exists(i): os.remove(i) + =20 + # Compile test suite + try: + returncode, exe, logfile =3D self._compileTest() + if returncode !=3D 0: + raise CompilationError(logfile) + except CompilationError as e: + Print("Compilation failed") + Print("See log: " + e.logfile) + return + Print("Compilation successful") + =20 + # Run test + logfile =3D pjoin(self.logdir, name+"_run.log") + retcode =3D self._executeTest(exe) + if returncode !=3D 0: + Print("Test failed") + Print("See log: " + logfile) + return + Print("Test successful") + =20 + # Return + return self._generateResults() + =20 \ No newline at end of file diff --git a/app-benchmarks/autobench/files/python/benchconfig.py b/app-b= enchmarks/autobench/files/python/benchconfig.py new file mode 100644 index 0000000..3b941db --- /dev/null +++ b/app-benchmarks/autobench/files/python/benchconfig.py @@ -0,0 +1,75 @@ +import sys, os, time +import subprocess as sp +from benchutils import * + +try: + needsinitialization =3D not initialized +except NameError: + needsinitialization =3D True + + +if needsinitialization: + isroot =3D os.getuid() =3D=3D 0 + modname =3D sys.argv[1] + =20 + # Script directories + curdir =3D os.path.abspath('.') + scriptdir =3D os.path.dirname(os.path.realpath(__file__)) + btldir =3D 'btl' + =20 + # Invariant directories: + # roots, tests + rootsdir =3D "/var/tmp/benchmarks/roots/" + testsdir =3D "/var/tmp/benchmarks/tests/" + =20 + # Library directory (lib32 vs. lib64) + libdir =3D sp.Popen \ + ('ABI=3D$(portageq envvar ABI); echo /usr/`portageq envvar LIBDIR_= $ABI`/', \ + stdout=3Dsp.PIPE, shell=3DTrue).communicate()[0].strip() + =20 + # Packages directory + if isroot: + pkgsdir =3D "/var/cache/benchmarks/packages/" + else: + pkgsdir =3D os.environ['HOME'] + "/.benchmarks/packages/" + =20 + # Report directory + if isroot: + reportdirb =3D "/var/cache/benchmarks/reports/" + else: + reportdirb =3D os.environ['HOME'] + "/.benchmarks/reports/" + reportdirb +=3D modname + "_" + time.strftime('%Y-%m-%d') + if os.path.exists(reportdirb): + n =3D 1 + while True: + reportdir =3D reportdirb + "_%i" % n + if not os.path.exists(reportdir): + break + n +=3D 1 + else: + reportdir =3D reportdirb + del reportdirb + =20 + # Logs directory + logdirb =3D "/var/log/benchmarks/" + modname + "_" + time.strftime('= %Y-%m-%d') + if os.path.exists(logdirb): + n =3D 1 + while True: + logdir =3D logdirb + "_%i"%n + if not os.path.exists(logdir): + break + n +=3D 1 + else: + logdir =3D logdirb + del logdirb + =20 +def makedirs(): + mkdir(rootsdir) + mkdir(testsdir) + mkdir(pkgsdir) + mkdir(reportdir) + mkdir(logdir) + =20 + =20 + =20 +inizialized =3D True \ No newline at end of file diff --git a/app-benchmarks/autobench/files/python/benchprint.py b/app-be= nchmarks/autobench/files/python/benchprint.py new file mode 100644 index 0000000..b91da66 --- /dev/null +++ b/app-benchmarks/autobench/files/python/benchprint.py @@ -0,0 +1,28 @@ +try: + needsinitialization =3D not initialized +except NameError: + needsinitialization =3D True + + +if needsinitialization: + class _Print: + def __init__(self, maxlevel=3D10): + self._level =3D 0 + self._maxlevel =3D maxlevel + =20 + def __call__(self, arg): + if self._level > self._maxlevel: + return + if self._level <=3D 0: + print str(arg) + return + print (self._level-1)*" " + "-- " + str(arg) + =20 + def up(self, n=3D1): + self._level =3D max(self._level-n, 0) + =20 + def down(self, n=3D1): + self._level =3D max(self._level+n, 0) + Print =3D _Print(3) + +initialized =3D True \ No newline at end of file diff --git a/app-benchmarks/autobench/files/python/benchutils.py b/app-be= nchmarks/autobench/files/python/benchutils.py new file mode 100644 index 0000000..824d441 --- /dev/null +++ b/app-benchmarks/autobench/files/python/benchutils.py @@ -0,0 +1,8 @@ +import os +import subprocess as sp + +def mkdir(dir): + if not os.path.exists(dir): + os.makedirs(dir) + =20 +run_cmd =3D lambda c : sp.Popen(c, stdout=3Dsp.PIPE).communicate()[0] \ No newline at end of file diff --git a/app-benchmarks/autobench/files/python/blas_accuracy.py b/app= -benchmarks/autobench/files/python/blas_accuracy.py index edbf343..890aa1e 100644 --- a/app-benchmarks/autobench/files/python/blas_accuracy.py +++ b/app-benchmarks/autobench/files/python/blas_accuracy.py @@ -1,20 +1,12 @@ -from os.path import join as pjoin import subprocess as sp import shlex, os +from os.path import join as pjoin + +from benchutils import * +from benchprint import Print from htmlreport import HTMLreport import basemodule - -try: - import matplotlib.pyplot as plt - import numpy as np - with_images =3D True -except ImportError: - sys.stderr.write('Error: matplotlib and numpy are needed' + \ - 'in order to generate the reports!\n') - sys.stderr.write('Continue anyway.\n\n') =20 - with_images =3D False - -run_cmd =3D lambda c : sp.Popen(c, stdout=3Dsp.PIPE).communicate()[0] +import benchconfig as cfg =20 class Module(basemodule.BaseModule): =20 @@ -39,27 +31,101 @@ class Module(basemodule.BaseModule): self.tests =3D self.avail =20 # Generate list of dat (result) files, relative to the testdir - self.files =3D [pjoin('accuracy_%s_%s.dat' % (op, name)) \ + self.files =3D [pjoin('accuracy_%s_%s.dat' % (op, self.libname))= \ for op in self.tests] =20 - def _compileTest(self, logfile, testdir, root, impl, *args, **kwargs= ): - exe =3D pjoin(testdir, 'test') + @staticmethod + def _testClass(): + return BLAS_accuracyTest + + =20 + def save_results(self, results): + basemodule.BaseModule.save_results(self, results, 'loglog') + =20 +class BLAS_accuracyTest(basemodule.BaseTest): + =20 + compileenv =3D {} + runenv =3D {} + =20 + def _compileTest(self): + self.compileenv =3D {} + =20 + # Flags and envvars lists + includes =3D [pjoin(self.root, 'usr/include')] + libraries =3D [] + libdirs =3D [self.libdir] + defines =3D ['NDEBUG'] + flags =3D [] + =20 + ## Interpret flags =20 + for flag in self._get_flags() + \ + shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip(= )): + flag =3D flag.strip() + if flag[:2] =3D=3D '-l': + libraries.append(flag[2:]) + elif flag[:2] =3D=3D '-L': + libdirs.append(flag[2:]) + elif flag[:2] =3D=3D '-I': + includes.append(flag[2:]) + else: + flags.append(flag) + =20 + # Set compile environment + self.compileenv['INCLUDE_PATH'] =3D ':'.join(includes) + self.compileenv['LIBRARY_PATH'] =3D ':'.join(libdirs) + self.compileenv['LD_LIBRARY_PATH'] =3D ':'.join(libdirs) + self.runenv['LD_LIBRARY_PATH'] =3D ':'.join(libdirs) + =20 + exe =3D pjoin(self.testdir, "test") source =3D "accuracy/main_blas.cpp" - flags =3D self._get_flags(root, impl, self.libdir) - cxxflags =3D run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip() + =20 + # Retrieve compiler cxx =3D 'g++' - cmd =3D [cxx, '-o', exe, source] + flags + shlex.split(cxxflags) - proc =3D sp.Popen(cmd, stdout=3Dfile(logfile, 'w'), stderr=3Dsp.= STDOUT) + cxx_portage =3D run_cmd(['portageq', 'envvar', 'CXX']).strip() + if cxx_portage !=3D '': + cxx =3D cxx_portage + if os.environ.has_key('CXX'): + cxx =3D os.environ['CXX'] + =20 + # Form command line arguments + args =3D [cxx, source, '-o', exe] + args +=3D ['-I'+I for I in includes] + args +=3D ['-l'+l for l in libraries] + args +=3D ['-L'+L for L in libdirs] + args +=3D ['-D'+D for D in defines] + args +=3D flags + =20 + # Open logfile or redirect to PIPE + logfile =3D file(pjoin(self.logdir, "compile.log"), 'w') + logfile.write(' '.join([n+'=3D'+v for n,v in self.compileenv.ite= ms()])) + logfile.write(' ' + ' '.join(args) + '\n' + 80*'-' + '\n') + logfile.flush() + =20 + # Execute + proc=3Dsp.Popen(args,stdout=3Dlogfile,stderr=3Dsp.STDOUT,env=3Ds= elf.compileenv) proc.wait() - return proc.returncode, exe + =20 + # Close, return + logfile.close() + return proc.returncode, exe, logfile.name + =20 =20 - def _executeTest(self, logfile, exe, testdir): - # TODO: control objdump and nm - logfile =3D file(logfile, 'w') - cmd =3D [exe] + self.tests - proc =3D sp.Popen(cmd, bufsize=3D1, stdout=3Dsp.PIPE, stderr=3Ds= p.PIPE, - cwd=3Dtestdir) - self.Print.down() + def _executeTest(self, exe): + # Log dynamic link + lddlogfile =3D file(pjoin(self.logdir, 'ldd.log'), 'w') + sp.Popen(['ldd', '-v', exe], stdout=3Dlddlogfile, env=3Dself.run= env).wait() + =20 + # Open pipe + logfile =3D file(pjoin(self.logdir, 'run.log'), 'w') + args =3D [exe] + self.tests + logfile.write(' '.join([n+'=3D'+v for n,v in self.runenv.items()= ]) + ' ') + logfile.write(' '.join(args) + '\n') + logfile.write(80*'-' + '\n') + proc =3D sp.Popen(args, bufsize=3D1, stdout=3Dsp.PIPE, stderr=3D= sp.PIPE,=20 + env=3Dself.runenv, cwd=3Dself.testdir) + =20 + # Interpret output + Print.down() while True: line =3D proc.stdout.readline() if not line: @@ -68,18 +134,12 @@ class Module(basemodule.BaseModule): if len(line.strip()) =3D=3D 0: continue if line[0] !=3D ' ': - self.Print.up() - self.Print(line.strip().split()[-1]) - self.Print.down() + Print.up() + Print(line.strip().split()[-1]) + Print.down() else: - self.Print(line.strip()) - self.Print.up() =20 + Print(line.strip()) + Print.up() =20 logfile.close() =20 proc.wait() return proc.returncode - - =20 - def save_results(self, results, figdir): - basemodule.BaseModule.save_results(self, results,figdir, 'loglog= ') - =20 - =20 diff --git a/app-benchmarks/autobench/files/python/blasbase.py b/app-benc= hmarks/autobench/files/python/blasbase.py index d2e4edd..664d706 100644 --- a/app-benchmarks/autobench/files/python/blasbase.py +++ b/app-benchmarks/autobench/files/python/blasbase.py @@ -38,7 +38,13 @@ class BLASBase(btlbase.BTLBase): 'trisolve_vector', 'matrix_matrix'] =20 btlbase.BTLBase._parse_args(self, args) - =20 + =20 + @staticmethod + def _testClass(): + return BLASTest + + +class BLASTest(btlbase.BTLTest): @staticmethod def _btl_source(): return "libs/BLAS/main.cpp" @@ -48,4 +54,4 @@ class BLASBase(btlbase.BTLBase): return ["libs/BLAS"] =20 def _btl_defines(self): - return ["CBLASNAME=3D" + self.libname, "BLAS_INTERFACE"] + return ["CBLASNAME=3D" + self.libname, "BLAS_INTERFACE"] \ No newline at end of file diff --git a/app-benchmarks/autobench/files/python/btlbase.py b/app-bench= marks/autobench/files/python/btlbase.py index 5e07178..1bcc529 100644 --- a/app-benchmarks/autobench/files/python/btlbase.py +++ b/app-benchmarks/autobench/files/python/btlbase.py @@ -1,99 +1,12 @@ import sys, os, shlex -import commands as cmd import subprocess as sp from os.path import join as pjoin + +from benchutils import * +from benchprint import Print from htmlreport import HTMLreport import basemodule - -try: - import matplotlib.pyplot as plt - import numpy as np - with_images =3D True -except ImportError: - sys.stderr.write('Error: matplotlib and numpy are needed' + \ - 'in order to generate the reports!\n') - sys.stderr.write('Continue anyway.\n\n') =20 - with_images =3D False - -run_cmd =3D lambda c : sp.Popen(c, stdout=3Dsp.PIPE).communicate()[0] - -def btlcompile(exe, source, btldir, includes, defines, libs, libdirs, ot= her, \ - logfile=3DNone): - """ - Helper function that compiles a C++ source based on btl. The functio= n - sets the compiler flags that are needed by btl (include directives, = link - with rt,...). More options are accepted as arguments: - =20 - exe: the generated executable - =20 - source: the C++ source - =20 - btldir: the base directory of the btl sources - =20 - includes: an iterable containing the include directories (without -I= ) - =20 - defines: an iterable of strings with define directives (without -D).= In case - of key-value pairs, the equal sign and the value have to be in the s= ame - string as the key: ['NDEBUG', 'FOO=3DBAR'] is transormed to - '-DNDEBUD -DFOO=3DBAR' - =20 - libs: the libraries to link against (without -l) - =20 - libdirs: the directories where the libraries are seeked (without -L) - =20 - other: an iterable with compiler flags - =20 - logfile: the path of the file where the log is saved. The directory = must - exist. If None, no log is generated. - """ - =20 - # Compile flags - incs =3D ( - "%s/actions" % btldir, - "%s/generic_bench" % btldir, - "%s/generic_bench/utils" % btldir, - "%s/libs/STL" % btldir - ) + tuple(includes) - incs =3D ['-I'+i for i in incs] - =20 - defs =3D ['-D'+d for d in ["NDEBUG"] + defines] - =20 - libs =3D ['-l'+l for l in ["rt"] + libs] - =20 - libdirs =3D ['-L'+L for L in libdirs] - =20 - cxxflags =3D shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS'])= .strip()) - =20 - otherfl =3D other - =20 - # Retrieve compiler - cxx =3D 'g++' - cxx_portage =3D run_cmd(['portageq', 'envvar', 'CXX']).strip() - if cxx_portage !=3D '': - cxx =3D cxx_portage - if os.environ.has_key('CXX'): - cxx =3D os.environ['CXX'] - =20 - # Compile command - cl =3D [cxx, '-o', exe, source]+incs+defs+libs+libdirs+cxxflags+othe= r - =20 - # Open logfile or redirect to PIPE=20 - if logfile is None: - fout =3D sp.PIPE - else: - fout =3D file(logfile, 'w') - fout.write(str(cl) + "\n" + 80*'-' + "\n") - fout.flush() - =20 - # Execute command - cp =3D sp.Popen(cl, stdout=3Dfout, stderr=3Dsp.STDOUT) - cp.wait() - =20 - # Close the log file (if any) - if logfile is not None: - fout.close() - =20 - return cp.returncode +import benchconfig as cfg =20 =20 class BTLBase(basemodule.BaseModule): @@ -103,29 +16,101 @@ class BTLBase(basemodule.BaseModule): self.files =3D [pjoin('bench_%s_%s.dat' % (op, self.libname)) \ for op in self.tests] =20 - def _compileTest(self, logfile, testdir, root, impl, libdir, \ - *args, **kwargs): - btldir =3D 'btl/' - exe =3D pjoin(testdir, "test") - returncode =3D btlcompile( - exe =3D exe, - source =3D pjoin(btldir, self._btl_source()), - btldir =3D btldir, - includes =3D [pjoin(btldir, d) for d in self._btl_includes()], - defines =3D self._btl_defines(), - libs =3D [], - libdirs =3D [libdir], - other =3D self._get_flags(root, impl, self.libdir), - logfile =3D logfile - ) - return returncode, exe - =20 - def _executeTest(self, logfile, exe, testdir): - # TODO: control objdump and nm - logfile =3D file(logfile, 'w') + def save_results(self, results): + basemodule.BaseModule.save_results(self, results, 'semilogx') = =20 + =20 + =20 +class BTLTest(basemodule.BaseTest): + =20 + compileenv =3D {} + runenv =3D {} + =20 + def _compileTest(self): + self.compileenv =3D {} + =20 + # Includes + includes =3D [pjoin(cfg.btldir, i) for i in \ + ('actions', 'generic_bench', 'generic_bench/utils', 'libs/STL') = + \ + tuple(self._btl_includes())] + [pjoin(self.root, 'usr/include')] + =20 + # Libraries + libraries =3D ['rt'] + =20 + # Libdirs + libdirs =3D [self.libdir] + =20 + # Defines + defines =3D ['NDEBUG'] + self._btl_defines() + =20 + # Flags + flags =3D [] + =20 + ## Interpret flags =20 + for flag in self._get_flags() + \ + shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip(= )): + flag =3D flag.strip() + if flag[:2] =3D=3D '-l': + libraries.append(flag[2:]) + elif flag[:2] =3D=3D '-L': + libdirs.append(flag[2:]) + elif flag[:2] =3D=3D '-I': + includes.append(flag[2:]) + else: + flags.append(flag) + =20 + # Set compile environment + self.compileenv['INCLUDE_PATH'] =3D ':'.join(includes) + self.compileenv['LIBRARY_PATH'] =3D ':'.join(libdirs) + self.compileenv['LD_LIBRARY_PATH'] =3D ':'.join(libdirs) + self.runenv['LD_LIBRARY_PATH'] =3D ':'.join(libdirs) + =20 + exe =3D pjoin(self.testdir, "test") + =20 + # Retrieve compiler + cxx =3D 'g++' + cxx_portage =3D run_cmd(['portageq', 'envvar', 'CXX']).strip() + if cxx_portage !=3D '': + cxx =3D cxx_portage + if os.environ.has_key('CXX'): + cxx =3D os.environ['CXX'] + =20 + # Form command line arguments + args =3D [cxx, pjoin(cfg.btldir, self._btl_source()), '-o', exe] + args +=3D ['-I'+I for I in includes] + args +=3D ['-l'+l for l in libraries] + args +=3D ['-L'+L for L in libdirs] + args +=3D ['-D'+D for D in defines] + args +=3D flags + =20 + # Open logfile or redirect to PIPE + logfile =3D file(pjoin(self.logdir, "compile.log"), 'w') + logfile.write(' '.join([n+'=3D'+v for n,v in self.compileenv.ite= ms()])) + logfile.write(' ' + ' '.join(args) + '\n' + 80*'-' + '\n') + logfile.flush() + =20 + # Execute + proc=3Dsp.Popen(args,stdout=3Dlogfile,stderr=3Dsp.STDOUT,env=3Ds= elf.compileenv) + proc.wait() + =20 + # Close, return + logfile.close() + return proc.returncode, exe, logfile.name + =20 + def _executeTest(self, exe): + # Log dynamic link + lddlogfile =3D file(pjoin(self.logdir, 'ldd.log'), 'w') + sp.Popen(['ldd', '-v', exe], stdout=3Dlddlogfile, env=3Dself.run= env).wait() + =20 + # Open pipe + logfile =3D file(pjoin(self.logdir, 'btlrun.log'), 'w') args =3D [exe] + self.tests + logfile.write(' '.join([n+'=3D'+v for n,v in self.runenv.items()= ]) + ' ') + logfile.write(' '.join(args) + '\n') + logfile.write(80*'-' + '\n') proc =3D sp.Popen(args, bufsize=3D1, stdout=3Dsp.PIPE, stderr=3D= sp.PIPE,=20 - cwd =3D testdir) + env=3Dself.runenv, cwd=3Dself.testdir) + =20 + # Interpret output while True: # Each operation test begins with a line on stderr errline =3D proc.stderr.readline() @@ -134,18 +119,18 @@ class BTLBase(basemodule.BaseModule): logfile.write(errline) resfile =3D errline.split()[-1] testname =3D resfile[6:-5-len(self.libname)] - self.Print(resfile) + Print(resfile) =20 # 100 different sizes for each operation test - self.Print.down() + Print.down() for i in xrange(100): outline =3D proc.stdout.readline() + # If the line is void, something gone wrong + if not outline: + return 1 logfile.write(outline) - self.Print(outline.strip()) - self.Print.up() + Print(outline.strip()) + Print.up() logfile.close() proc.wait() - return proc.returncode - =20 - def save_results(self, results, figdir): - basemodule.BaseModule.save_results(self, results,figdir, 'semilo= gx') + return proc.returncode \ No newline at end of file diff --git a/app-benchmarks/autobench/files/python/lapack.py b/app-benchm= arks/autobench/files/python/lapack.py index 136d837..e618380 100644 --- a/app-benchmarks/autobench/files/python/lapack.py +++ b/app-benchmarks/autobench/files/python/lapack.py @@ -27,6 +27,13 @@ class Module(btlbase.BTLBase): btlbase.BTLBase._parse_args(self, args) =20 @staticmethod + def _testClass(): + return LapackTest + =20 + =20 + =20 +class LapackTest(btlbase.BTLTest): + @staticmethod def _btl_source(): return "libs/LAPACK/main.cpp" =20 @@ -34,5 +41,7 @@ class Module(btlbase.BTLBase): def _btl_includes(): return ["libs/BLAS", "libs/LAPACK"] =20 - def _btl_defines(self): - return ["LAPACKNAME=3D" + self.libname] + @staticmethod + def _btl_defines(): + return ["LAPACKNAME=3Dlapack"] + =20 \ No newline at end of file diff --git a/app-benchmarks/autobench/files/python/main.py b/app-benchmar= ks/autobench/files/python/main.py index 3a02791..79b41e9 100644 --- a/app-benchmarks/autobench/files/python/main.py +++ b/app-benchmarks/autobench/files/python/main.py @@ -1,85 +1,29 @@ #! /usr/bin/env python2 =20 -import os, sys, shlex +import os, sys, shlex, time from os.path import join as pjoin -from PortageUtils import * import subprocess as sp -import time -=20 -# Retrieve relevant files/directories -# TODO: use external config module to share these variables (or use envi= ron?) -curdir =3D os.path.abspath('.') -scriptdir =3D os.path.dirname(os.path.realpath(__file__)) -rootsdir =3D "/var/tmp/benchmarks/roots/" -testsdir =3D "/var/tmp/benchmarks/tests/" -if os.getuid() =3D=3D 0: - pkgsdir =3D "/var/cache/benchmarks/packages/" - figdirb =3D "/var/cache/benchmarks/results/" -else: - pkgsdir =3D os.environ['HOME'] + "/.benchmarks/packages/" - figdirb =3D os.environ['HOME'] + "/.benchmarks/results/" - =20 -# Library directory (lib32 vs. lib64) -libdir =3D sp.Popen \ - ('ABI=3D$(portageq envvar ABI); echo /usr/`portageq envvar LIBDIR_$ABI= `/', \ - stdout=3Dsp.PIPE, shell=3DTrue).communicate()[0].strip() - =20 -# Figures directory -figdir =3D figdirb + time.strftime('%Y-%m-%d') -if os.path.exists(figdir): - n =3D 1 - while True: - figdir =3D figdirb + time.strftime('%Y-%m-%d') + "_%i"%n - if not os.path.exists(figdir): - os.makedirs(figdir) - break - n +=3D 1 -else: - os.makedirs(figdir) - =20 -# Logs directory -logdir =3D "/var/log/benchmarks/" + time.strftime('%Y-%m-%d') -if os.path.exists(logdir): - n =3D 1 - while True: - logdir =3D "/var/log/benchmarks/" + time.strftime('%Y-%m-%d') + = "_%i"%n - if not os.path.exists(logdir): - os.makedirs(logdir) - break - n +=3D 1 -else: - os.makedirs(logdir) =20 def print_usage(): - print "Usage: benchmarks [blas|cblas|lapack] file args" =20 - =20 -class _Print: - def __init__(self, maxlevel=3D10): - self._level =3D 0 - self._maxlevel =3D maxlevel - =20 - def __call__(self, arg): - if self._level > self._maxlevel: - return - if self._level <=3D 0: - print str(arg) - return - print (self._level-1)*" " + "-- " + str(arg) - =20 - def up(self, n=3D1): - self._level =3D max(self._level-n, 0) - =20 - def down(self, n=3D1): - self._level =3D max(self._level+n, 0) -Print =3D _Print(3) + print "Usage: benchmarks [blas|cblas|lapack] file args" + +if len(sys.argv) < 3: + print_usage() + exit(1) + +from PortageUtils import * +import benchconfig as cfg +from benchprint import Print + =20 # Import the desired module or print help and exit try: testsfname =3D os.path.abspath(sys.argv[2]) - os.chdir(scriptdir) + os.chdir(cfg.scriptdir) tmp =3D __import__(sys.argv[1], fromlist =3D ['Module']) - mod =3D tmp.Module(Print, libdir, sys.argv[3:]) + mod =3D tmp.Module(sys.argv[3:]) del tmp + cfg.makedirs() except ImportError, IndexError: print_usage() exit(1) @@ -177,9 +121,9 @@ print for tn,(name,test) in enumerate(tests.items(),1): Print("BEGIN TEST %i - %s" % (tn, name)) =20 - pkgdir =3D pjoin(pkgsdir, name) - root =3D pjoin(rootsdir, name) - tlogdir =3D pjoin(logdir, name) + pkgdir =3D pjoin(cfg.pkgsdir, name) + root =3D pjoin(cfg.rootsdir, name) + tlogdir =3D pjoin(cfg.logdir, name) os.path.exists(tlogdir) or os.makedirs(tlogdir) =20 # Emerge package @@ -227,27 +171,26 @@ for tn,(name,test) in enumerate(tests.items(),1): Print.down() =20 # Run the test suite - testdir =3D os.path.join(testsdir, name, impl) - test['results'][impl] =3D \ - mod.run_test(root, impl, testdir, env=3Dtest['env'], logdir=3D= tlogdir) + testdir =3D os.path.join(cfg.testsdir, name, impl) + t =3D mod.getTest(root, impl, testdir, logdir=3Dtlogdir) + test['results'][impl] =3D t.run_test() Print.up() =20 Print.up() print =20 =20 -# Reports will be saved in figdir +# Reports will be saved in cfg.reportdir =20 # Results are reordered: # results # |-(name1, impl1) -> resultobject11 # |-(name1, impl2) -> resultobject12 -# |-(name2, impl1) -> resultobject21 -os.path.exists(figdir) or os.makedirs(figdir) =20 +# |-(name2, impl1) -> resultobject21 =20 results =3D {} for (name,test) in tests.items(): if test.has_key('implementations'): for impl in test['implementations']: results[(name, impl)] =3D test['results'][impl] =20 -mod.save_results(results, figdir) +mod.save_results(results)