public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Andrea Arteaga" <andyspiros@gmail.com>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/auto-numerical-bench:master commit in: app-benchmarks/autobench/files/python/
Date: Mon,  4 Jul 2011 21:38:59 +0000 (UTC)	[thread overview]
Message-ID: <30b1b4ec2c495adaab4a7c33656ce994a661b4ea.spiros@gentoo> (raw)

commit:     30b1b4ec2c495adaab4a7c33656ce994a661b4ea
Author:     spiros <andyspiros <AT> gmail <DOT> com>
AuthorDate: Mon Jul  4 21:38:32 2011 +0000
Commit:     Andrea Arteaga <andyspiros <AT> gmail <DOT> com>
CommitDate: Mon Jul  4 21:38:32 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/auto-numerical-bench.git;a=commit;h=30b1b4ec

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-benchmarks/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
 
 try:
     import matplotlib.pyplot as plt
@@ -14,12 +18,9 @@ except ImportError:
     sys.stderr.write('Continue anyway.\n\n')    
     with_images = False
 
-run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
 
 class BaseModule:
-    def __init__(self, Print, libdir, args):
-        self.Print = Print
-        self.libdir = libdir
+    def __init__(self, args):
         self.summary = False
         self.summary_only = False
         
@@ -37,119 +38,26 @@ class BaseModule:
                 passargs += [i]
         
         self._parse_args(passargs)
-           
-    # Alternatives-2 version with pkg-config
-    def _get_flags(self, root, impl, libdir):
-        while libdir[0] == '/':
-            libdir = libdir[1:]
-        # Retrieve pkgconfig settings and map the directories to the new root
-        path = pjoin(root, "etc/env.d/alternatives", \
-          self.libname,impl,libdir, "pkgconfig")
-        cmd = ['pkg-config', '--libs', '--cflags', self.libname]
-        env = {'PKG_CONFIG_PATH':path}
-        pkgconf = sp.Popen(cmd, stdout=sp.PIPE, env=env).communicate()[0]
-        pkgconf = pkgconf.replace('-L/', '-L'+root+'/')
-        pkgconf = pkgconf.replace('-I/', '-I'+root+'/')
-        return shlex.split(pkgconf)
         
     # Alternatives-2 version
+    
     def get_impls(self, root):
         output = sp.Popen(
           ['eselect', '--no-color', '--brief', self.libname, 'list'],
           env={'ROOT' : root}, stdout=sp.PIPE).communicate()[0]
         return output.strip().split('\n')
-        
-    # Base version
-    def _generateResults(self, files):
-        return dict(zip(self.tests, files))
-    
-    def run_test(self, root, impl, testdir, env, logdir):
-        # Convenient renames and definition of report files
-        Print = self.Print
-        name = self.libname
-        files = [pjoin(testdir,f) for f in self.files]
-        if self.libdir[0] == '/':
-            libdir = root+self.libdir
-        else:
-            libdir = pjoin(root, self.libdir)
-        
-        # Create dir. If all results already exist use them and do not perform
-        # the tests, otherwise remove every old results.
-        runtests = False
-        if os.path.exists(testdir):
-            runtests = not all([os.path.exists(i) for i in files])
-        else:
-            os.makedirs(testdir)
-            runtests = True
-        
-        if not runtests:
-            Print("Not testing: results exist")
-            return self._generateResults(files)
-        
-        for i in files:
-            if os.path.exists(i): os.remove(i)
-            
-        # Prepare the environment
-        if env.has_key('LIBRARY_PATH'):
-            env['LIBRARY_PATH'] = libdir + ":" + env['LIBRARY_PATH']
-        else:
-            env['LIBRARY_PATH'] = libdir
-            
-        if env.has_key('INCLUDE_PATH'):
-            env['INCLUDE_PATH'] = \
-              pjoin(root, "usr/include") + ":" + env['INCLUDE_PATH']
-        else:
-            env['INCLUDE_PATH'] = pjoin(root, "usr/include")
-            
-        if env.has_key('LD_LIBRARY_PATH'):
-            env['LD_LIBRARY_PATH'] = \
-              libdir + ":" + env['LD_LIBRARY_PATH']
-        else:
-            env['LD_LIBRARY_PATH'] = libdir
-        
-        # Backup the environment
-        oldenv = {}
-        for k in env.keys():
-            oldenv[k] = \
-              (os.environ.has_key(k) and (os.environ[k],) or (None,))[0]
-        
-        # Set the new environment
-        for k,v in env.items():
-            os.environ[k] = v
-        
-        # Compile test suite
-        logfile = os.path.join(logdir, name+"_comp.log")
-        returncode, exe = self._compileTest(logfile=logfile, testdir=testdir, \
-          root=root, impl=impl, libdir=libdir)
-        if returncode != 0:
-            Print("Compilation failed")
-            Print("See log: " + logfile)
-            return
-        Print("Compilation successful")
-        
-        # Run test
-        logfile = pjoin(logdir, name+"_run.log")
-        retcode = self._executeTest(logfile=logfile, exe=exe, testdir=testdir)
-        if returncode != 0:
-            Print("Test failed")
-            Print("See log: " + logfile)
-            return
-        Print("Test successful")
-        
-        # Restore the old environment
-        for k in env.keys():
-            if oldenv[k] != None:
-                os.environ[k] = oldenv[k]
-            elif os.environ.has_key(k):
-                del os.environ[k]
-                
-        # Return
-        return self._generateResults(files)
-    
+           
+    def getTest(self, root, impl, testdir, logdir):
+        TestClass = self._testClass()
+        t = TestClass(root, impl, testdir, logdir)
+        t.libname = self.libname
+        t.tests = self.tests
+        t.files = self.files
+        return t
     
-    def save_results(self, results, figdir, plottype='plot'):
+    def save_results(self, results, plottype='plot'):
         if not with_images:
-            self.Print("Report generation skipped - missing libraries")
+            Print("Report generation skipped - missing libraries")
             return
         
         if plottype == 'plot': plotf = plt.plot
@@ -165,11 +73,13 @@ class BaseModule:
             newresults[test] = {}
             for nameimpl in results:
                 nameimplstr = pjoin(*nameimpl)
+                if results[nameimpl] == None:
+                    continue
                 resdat = results[nameimpl][test]
                 newresults[test][nameimplstr] = resdat
         
         # Begin the HTML report
-        htmlfname = pjoin(figdir, 'index.html')
+        htmlfname = pjoin(cfg.reportdir, 'index.html')
         html = HTMLreport(htmlfname)
         
         # Generate summary - a single image with all plots
@@ -185,10 +95,10 @@ class BaseModule:
                     plotf(x,y, label=impl, hold=True)
                 plt.legend(loc='best')
                 plt.grid(True)
-            fname = pjoin(figdir, 'summary.png')
+            fname = pjoin(cfg.reportdir, 'summary.png')
             plt.savefig(fname, format='png')
             html.addFig("Summary", image=os.path.basename(fname), width='95%')
-            self.Print('Summary figure saved: ' + fname)
+            Print('Summary figure saved: ' + fname)
                 
         # Generate plots
         if not self.summary_only:
@@ -199,9 +109,123 @@ class BaseModule:
                     plotf(x,y, label=impl, hold=True)
                 plt.legend(loc='best')
                 plt.grid(True)
-                fname = pjoin(figdir, test+".png")
+                fname = pjoin(cfg.reportdir, test+".png")
                 plt.savefig(fname, format='png')
                 html.addFig(test, image=os.path.basename(fname))
-                self.Print('Figure ' + fname + ' saved')
+                Print('Figure ' + fname + ' saved')
         
         html.close()
+        Print('HTML report generated: ' + htmlfname)
+
+class CompilationError(Exception):
+    def __init__(self, logfile):
+        self.logfile = logfile
+
+
+class BaseTest:
+    libname = None
+    tests = None
+    files = None
+    
+    def __init__(self, root, impl, testdir, logdir):
+        self.root = root
+        self.impl = impl
+        self.testdir = testdir
+        self.logdir = pjoin(logdir, impl)
+        self.compileenv = {}
+        self.runenv = {}
+        
+        mkdir(self.logdir)
+        
+        self.libdir = cfg.libdir
+        while self.libdir[0] == '/':
+            self.libdir = self.libdir[1:]
+        self.libdir = pjoin(self.root, self.libdir)
+        
+    # Base version
+    def _generateResults(self):
+        return dict(zip(self.tests, self.files))
+           
+    # Alternatives-2 version with pkg-config
+    def _get_flags(self):
+        libdir = cfg.libdir
+        while libdir[0] == '/':
+            libdir = libdir[1:]
+        
+        # Retrieve pkgconfig settings and map the directories to the new root
+        path = pjoin(self.root, "etc/env.d/alternatives", \
+          self.libname, self.impl, libdir, "pkgconfig")
+        cmd = ['pkg-config', '--libs', '--cflags', self.libname]
+        env = {
+          'PKG_CONFIG_PATH' : path,
+          'PKG_CONFIG_LIBDIR' : '',
+          'PKG_CONFIG_SYSROOT_DIR' : self.root
+        }
+        proc = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.STDOUT, env=env)
+        pkgconf = proc.communicate()[0]
+        
+        # Write logfile
+        logfname = pjoin(self.logdir, 'pkgconfig.log')
+        logfile = file(logfname, 'w')
+        logfile.write('PKG_CONFIG_PATH='+path + '\n')
+        logfile.write('PKG_CONFIG_LIBDIR=""' + '\n')
+        logfile.write('PKG_CONFIG_SYSROOT_DIR='+self.root + '\n')
+        logfile.write(' '.join(cmd) + '\n')
+        logfile.write(80*'-' + '\n')
+        logfile.write(pkgconf)
+        logfile.close()
+        
+        if proc.returncode != 0:
+            raise CompilationError(logfname)
+        
+        return shlex.split(pkgconf)
+    
+    def run_test(self):
+        # Convenient renames and definition of report files
+        name = self.libname
+        root = self.root
+        testdir = self.testdir
+        self.files = [pjoin(testdir,f) for f in self.files]
+        env = {} # TODO: remove this
+        if cfg.libdir[0] == '/':
+            libdir = root+cfg.libdir
+        else:
+            libdir = pjoin(root, cfg.libdir)
+        
+        # Create dir. If all results already exist use them and do not perform
+        # the tests, otherwise remove every old results.
+        runtests = False
+        if os.path.exists(testdir):
+            runtests = not all([os.path.exists(i) for i in self.files])
+        else:
+            os.makedirs(testdir)
+            runtests = 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)
+        
+        # Compile test suite
+        try:
+            returncode, exe, logfile = self._compileTest()
+            if returncode != 0:
+                raise CompilationError(logfile)
+        except CompilationError as e:
+            Print("Compilation failed")
+            Print("See log: " + e.logfile)
+            return
+        Print("Compilation successful")
+        
+        # Run test
+        logfile = pjoin(self.logdir, name+"_run.log")
+        retcode = self._executeTest(exe)
+        if returncode != 0:
+            Print("Test failed")
+            Print("See log: " + logfile)
+            return
+        Print("Test successful")
+                
+        # Return
+        return self._generateResults()
+    
\ No newline at end of file

diff --git a/app-benchmarks/autobench/files/python/benchconfig.py b/app-benchmarks/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 = not initialized
+except NameError:
+    needsinitialization = True
+
+
+if needsinitialization:
+    isroot = os.getuid() == 0
+    modname = sys.argv[1]
+    
+    # Script directories
+    curdir = os.path.abspath('.')
+    scriptdir = os.path.dirname(os.path.realpath(__file__))
+    btldir = 'btl'
+    
+    # Invariant directories:
+    # roots, tests
+    rootsdir = "/var/tmp/benchmarks/roots/"
+    testsdir = "/var/tmp/benchmarks/tests/"
+    
+    # Library directory (lib32 vs. lib64)
+    libdir = sp.Popen \
+      ('ABI=$(portageq envvar ABI); echo /usr/`portageq envvar LIBDIR_$ABI`/', \
+      stdout=sp.PIPE, shell=True).communicate()[0].strip()
+    
+    # Packages directory
+    if isroot:
+        pkgsdir = "/var/cache/benchmarks/packages/"
+    else:
+        pkgsdir = os.environ['HOME'] + "/.benchmarks/packages/"
+    
+    # Report directory
+    if isroot:
+        reportdirb = "/var/cache/benchmarks/reports/"
+    else:
+        reportdirb = os.environ['HOME'] + "/.benchmarks/reports/"
+    reportdirb += modname + "_" + time.strftime('%Y-%m-%d')
+    if os.path.exists(reportdirb):
+        n = 1
+        while True:
+            reportdir = reportdirb + "_%i" % n
+            if not os.path.exists(reportdir):
+                break
+            n += 1
+    else:
+        reportdir = reportdirb
+    del reportdirb
+    
+    # Logs directory
+    logdirb = "/var/log/benchmarks/" + modname + "_" + time.strftime('%Y-%m-%d')
+    if os.path.exists(logdirb):
+        n = 1
+        while True:
+            logdir = logdirb + "_%i"%n
+            if not os.path.exists(logdir):
+                break
+            n += 1
+    else:
+        logdir = logdirb
+    del logdirb
+    
+def makedirs():
+    mkdir(rootsdir)
+    mkdir(testsdir)
+    mkdir(pkgsdir)
+    mkdir(reportdir)
+    mkdir(logdir)
+    
+    
+    
+inizialized = True
\ No newline at end of file

diff --git a/app-benchmarks/autobench/files/python/benchprint.py b/app-benchmarks/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 = not initialized
+except NameError:
+    needsinitialization = True
+
+
+if needsinitialization:
+    class _Print:
+        def __init__(self, maxlevel=10):
+            self._level = 0
+            self._maxlevel = maxlevel
+        
+        def __call__(self, arg):
+            if self._level > self._maxlevel:
+                return
+            if self._level <= 0:
+                print str(arg)
+                return
+            print (self._level-1)*"  " + "-- " + str(arg)
+            
+        def up(self, n=1):
+            self._level = max(self._level-n, 0)
+        
+        def down(self, n=1):
+            self._level = max(self._level+n, 0)
+    Print = _Print(3)
+
+initialized = True
\ No newline at end of file

diff --git a/app-benchmarks/autobench/files/python/benchutils.py b/app-benchmarks/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)
+        
+run_cmd = lambda c : sp.Popen(c, stdout=sp.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 = 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')    
-    with_images = False
-
-run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
+import benchconfig as cfg
 
 class Module(basemodule.BaseModule):
     
@@ -39,27 +31,101 @@ class Module(basemodule.BaseModule):
             self.tests = self.avail
          
         # Generate list of dat (result) files, relative to the testdir
-        self.files = [pjoin('accuracy_%s_%s.dat' % (op, name)) \
+        self.files = [pjoin('accuracy_%s_%s.dat' % (op, self.libname)) \
           for op in self.tests]
         
-    def _compileTest(self, logfile, testdir, root, impl, *args, **kwargs):
-        exe = pjoin(testdir, 'test')
+    @staticmethod
+    def _testClass():
+        return BLAS_accuracyTest
+
+    
+    def save_results(self, results):
+        basemodule.BaseModule.save_results(self, results, 'loglog')
+            
+class BLAS_accuracyTest(basemodule.BaseTest):
+    
+    compileenv = {}
+    runenv = {}
+        
+    def _compileTest(self):
+        self.compileenv = {}
+        
+        # Flags and envvars lists
+        includes = [pjoin(self.root, 'usr/include')]
+        libraries = []
+        libdirs = [self.libdir]
+        defines = ['NDEBUG']
+        flags = []
+        
+        ## Interpret flags        
+        for flag in self._get_flags() + \
+          shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()):
+            flag = flag.strip()
+            if flag[:2] == '-l':
+                libraries.append(flag[2:])
+            elif flag[:2] == '-L':
+                libdirs.append(flag[2:])
+            elif flag[:2] == '-I':
+                includes.append(flag[2:])
+            else:
+                flags.append(flag)
+        
+        # Set compile environment
+        self.compileenv['INCLUDE_PATH'] = ':'.join(includes)
+        self.compileenv['LIBRARY_PATH'] = ':'.join(libdirs)
+        self.compileenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
+        self.runenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
+        
+        exe = pjoin(self.testdir, "test")
         source = "accuracy/main_blas.cpp"
-        flags = self._get_flags(root, impl, self.libdir)
-        cxxflags = run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()
+    
+        # Retrieve compiler
         cxx = 'g++'
-        cmd = [cxx, '-o', exe, source] + flags + shlex.split(cxxflags)
-        proc = sp.Popen(cmd, stdout=file(logfile, 'w'), stderr=sp.STDOUT)
+        cxx_portage = run_cmd(['portageq', 'envvar', 'CXX']).strip()
+        if cxx_portage != '':
+            cxx = cxx_portage
+        if os.environ.has_key('CXX'):
+            cxx = os.environ['CXX']
+        
+        # Form command line arguments
+        args = [cxx, source, '-o', 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 or redirect to PIPE
+        logfile = file(pjoin(self.logdir, "compile.log"), 'w')
+        logfile.write(' '.join([n+'='+v for n,v in self.compileenv.items()]))
+        logfile.write(' ' + ' '.join(args) + '\n' + 80*'-' + '\n')
+        logfile.flush()
+        
+        # Execute
+        proc=sp.Popen(args,stdout=logfile,stderr=sp.STDOUT,env=self.compileenv)
         proc.wait()
-        return proc.returncode, exe
+        
+        # Close, return
+        logfile.close()
+        return proc.returncode, exe, logfile.name
+    
     
-    def _executeTest(self, logfile, exe, testdir):
-        # TODO: control objdump and nm
-        logfile = file(logfile, 'w')
-        cmd = [exe] + self.tests
-        proc = sp.Popen(cmd, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE,
-          cwd=testdir)
-        self.Print.down()
+    def _executeTest(self, exe):
+        # Log dynamic link
+        lddlogfile = file(pjoin(self.logdir, 'ldd.log'), 'w')
+        sp.Popen(['ldd', '-v', exe], stdout=lddlogfile, env=self.runenv).wait()
+        
+        # Open pipe
+        logfile = file(pjoin(self.logdir, 'run.log'), 'w')
+        args = [exe] + self.tests
+        logfile.write(' '.join([n+'='+v for n,v in self.runenv.items()]) + ' ')
+        logfile.write(' '.join(args) + '\n')
+        logfile.write(80*'-' + '\n')
+        proc = sp.Popen(args, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE, 
+          env=self.runenv, cwd=self.testdir)
+        
+        # Interpret output
+        Print.down()
         while True:
             line = proc.stdout.readline()
             if not line:
@@ -68,18 +134,12 @@ class Module(basemodule.BaseModule):
             if len(line.strip()) == 0:
                 continue
             if line[0] != ' ':
-                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()          
+                Print(line.strip())
+        Print.up()          
         logfile.close()      
         proc.wait()
         return proc.returncode
-
-    
-    def save_results(self, results, figdir):
-        basemodule.BaseModule.save_results(self, results,figdir, 'loglog')
-            
-            

diff --git a/app-benchmarks/autobench/files/python/blasbase.py b/app-benchmarks/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']
         
         btlbase.BTLBase._parse_args(self, args)
-    
+        
+    @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"]
     
     def _btl_defines(self):
-        return ["CBLASNAME=" + self.libname, "BLAS_INTERFACE"]
+        return ["CBLASNAME=" + self.libname, "BLAS_INTERFACE"]
\ No newline at end of file

diff --git a/app-benchmarks/autobench/files/python/btlbase.py b/app-benchmarks/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 = 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')    
-    with_images = False
-
-run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
-
-def btlcompile(exe, source, btldir, includes, defines, libs, libdirs, other, \
-  logfile=None):
-    """
-    Helper function that compiles a C++ source based on btl. The function
-    sets the compiler flags that are needed by btl (include directives, link
-    with rt,...). More options are accepted as arguments:
-    
-    exe: the generated executable
-    
-    source: the C++ source
-    
-    btldir: the base directory of the btl sources
-    
-    includes: an iterable containing the include directories (without -I)
-    
-    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 same
-    string as the key: ['NDEBUG', 'FOO=BAR'] is transormed to
-    '-DNDEBUD -DFOO=BAR'
-    
-    libs: the libraries to link against (without -l)
-    
-    libdirs: the directories where the libraries are seeked (without -L)
-    
-    other: an iterable with compiler flags
-    
-    logfile: the path of the file where the log is saved. The directory must
-    exist. If None, no log is generated.
-    """
-    
-    # Compile flags
-    incs = (
-      "%s/actions" % btldir,
-      "%s/generic_bench" % btldir,
-      "%s/generic_bench/utils" % btldir,
-      "%s/libs/STL" % btldir
-    ) + tuple(includes)
-    incs = ['-I'+i for i in incs]
-    
-    defs = ['-D'+d for d in ["NDEBUG"] + defines]
-    
-    libs = ['-l'+l for l in ["rt"] + libs]
-    
-    libdirs = ['-L'+L for L in libdirs]
-    
-    cxxflags = shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip())
-    
-    otherfl = other
-    
-    # Retrieve compiler
-    cxx = 'g++'
-    cxx_portage = run_cmd(['portageq', 'envvar', 'CXX']).strip()
-    if cxx_portage != '':
-        cxx = cxx_portage
-    if os.environ.has_key('CXX'):
-        cxx = os.environ['CXX']
-    
-    # Compile command
-    cl = [cxx, '-o', exe, source]+incs+defs+libs+libdirs+cxxflags+other
-    
-    # Open logfile or redirect to PIPE 
-    if logfile is None:
-        fout = sp.PIPE
-    else:
-        fout = file(logfile, 'w')
-        fout.write(str(cl) + "\n" + 80*'-' + "\n")
-        fout.flush()
-    
-    # Execute command
-    cp = sp.Popen(cl, stdout=fout, stderr=sp.STDOUT)
-    cp.wait()
-    
-    # Close the log file (if any)
-    if logfile is not None:
-        fout.close()
-    
-    return cp.returncode
+import benchconfig as cfg
 
 
 class BTLBase(basemodule.BaseModule):
@@ -103,29 +16,101 @@ class BTLBase(basemodule.BaseModule):
         self.files = [pjoin('bench_%s_%s.dat' % (op, self.libname)) \
           for op in self.tests]
     
-    def _compileTest(self, logfile, testdir, root, impl, libdir, \
-      *args, **kwargs):
-        btldir = 'btl/'
-        exe = pjoin(testdir, "test")
-        returncode = btlcompile(
-          exe = exe,
-          source = pjoin(btldir, self._btl_source()),
-          btldir = btldir,
-          includes = [pjoin(btldir, d) for d in self._btl_includes()],
-          defines = self._btl_defines(),
-          libs = [],
-          libdirs = [libdir],
-          other = self._get_flags(root, impl, self.libdir),
-          logfile = logfile
-        )
-        return returncode, exe
-    
-    def _executeTest(self, logfile, exe, testdir):
-        # TODO: control objdump and nm
-        logfile = file(logfile, 'w')
+    def save_results(self, results):
+        basemodule.BaseModule.save_results(self, results, 'semilogx')     
+        
+    
+class BTLTest(basemodule.BaseTest):
+    
+    compileenv = {}
+    runenv = {}
+    
+    def _compileTest(self):
+        self.compileenv = {}
+        
+        # Includes
+        includes = [pjoin(cfg.btldir, i) for i in \
+        ('actions', 'generic_bench', 'generic_bench/utils', 'libs/STL') + \
+        tuple(self._btl_includes())] + [pjoin(self.root, 'usr/include')]
+        
+        # Libraries
+        libraries = ['rt']
+        
+        # Libdirs
+        libdirs = [self.libdir]
+        
+        # Defines
+        defines = ['NDEBUG'] + self._btl_defines()
+        
+        # Flags
+        flags = []
+        
+        ## Interpret flags        
+        for flag in self._get_flags() + \
+          shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()):
+            flag = flag.strip()
+            if flag[:2] == '-l':
+                libraries.append(flag[2:])
+            elif flag[:2] == '-L':
+                libdirs.append(flag[2:])
+            elif flag[:2] == '-I':
+                includes.append(flag[2:])
+            else:
+                flags.append(flag)
+        
+        # Set compile environment
+        self.compileenv['INCLUDE_PATH'] = ':'.join(includes)
+        self.compileenv['LIBRARY_PATH'] = ':'.join(libdirs)
+        self.compileenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
+        self.runenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
+        
+        exe = pjoin(self.testdir, "test")
+    
+        # Retrieve compiler
+        cxx = 'g++'
+        cxx_portage = run_cmd(['portageq', 'envvar', 'CXX']).strip()
+        if cxx_portage != '':
+            cxx = cxx_portage
+        if os.environ.has_key('CXX'):
+            cxx = os.environ['CXX']
+        
+        # Form command line arguments
+        args = [cxx, pjoin(cfg.btldir, self._btl_source()), '-o', 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 or redirect to PIPE
+        logfile = file(pjoin(self.logdir, "compile.log"), 'w')
+        logfile.write(' '.join([n+'='+v for n,v in self.compileenv.items()]))
+        logfile.write(' ' + ' '.join(args) + '\n' + 80*'-' + '\n')
+        logfile.flush()
+        
+        # Execute
+        proc=sp.Popen(args,stdout=logfile,stderr=sp.STDOUT,env=self.compileenv)
+        proc.wait()
+        
+        # Close, return
+        logfile.close()
+        return proc.returncode, exe, logfile.name
+    
+    def _executeTest(self, exe):
+        # Log dynamic link
+        lddlogfile = file(pjoin(self.logdir, 'ldd.log'), 'w')
+        sp.Popen(['ldd', '-v', exe], stdout=lddlogfile, env=self.runenv).wait()
+        
+        # Open pipe
+        logfile = file(pjoin(self.logdir, 'btlrun.log'), 'w')
         args = [exe] + self.tests
+        logfile.write(' '.join([n+'='+v for n,v in self.runenv.items()]) + ' ')
+        logfile.write(' '.join(args) + '\n')
+        logfile.write(80*'-' + '\n')
         proc = sp.Popen(args, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE, 
-          cwd = testdir)
+          env=self.runenv, cwd=self.testdir)
+        
+        # Interpret output
         while True:
             # Each operation test begins with a line on stderr
             errline = proc.stderr.readline()
@@ -134,18 +119,18 @@ class BTLBase(basemodule.BaseModule):
             logfile.write(errline)
             resfile = errline.split()[-1]
             testname = resfile[6:-5-len(self.libname)]
-            self.Print(resfile)
+            Print(resfile)
             
             # 100 different sizes for each operation test
-            self.Print.down()
+            Print.down()
             for i in xrange(100):
                 outline = 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
-    
-    def save_results(self, results, figdir):
-        basemodule.BaseModule.save_results(self, results,figdir, 'semilogx')
+        return proc.returncode
\ No newline at end of file

diff --git a/app-benchmarks/autobench/files/python/lapack.py b/app-benchmarks/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)
     
     @staticmethod
+    def _testClass():
+        return LapackTest
+    
+    
+    
+class LapackTest(btlbase.BTLTest):
+    @staticmethod
     def _btl_source():
         return "libs/LAPACK/main.cpp"
     
@@ -34,5 +41,7 @@ class Module(btlbase.BTLBase):
     def _btl_includes():
         return ["libs/BLAS", "libs/LAPACK"]
     
-    def _btl_defines(self):
-        return ["LAPACKNAME=" + self.libname]
+    @staticmethod
+    def _btl_defines():
+        return ["LAPACKNAME=lapack"]
+    
\ No newline at end of file

diff --git a/app-benchmarks/autobench/files/python/main.py b/app-benchmarks/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
 
-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
- 
-# Retrieve relevant files/directories
-# TODO: use external config module to share these variables (or use environ?)
-curdir = os.path.abspath('.')
-scriptdir = os.path.dirname(os.path.realpath(__file__))
-rootsdir = "/var/tmp/benchmarks/roots/"
-testsdir = "/var/tmp/benchmarks/tests/"
-if os.getuid() == 0:
-    pkgsdir = "/var/cache/benchmarks/packages/"
-    figdirb = "/var/cache/benchmarks/results/"
-else:
-    pkgsdir = os.environ['HOME'] + "/.benchmarks/packages/"
-    figdirb = os.environ['HOME'] + "/.benchmarks/results/"
-    
-# Library directory (lib32 vs. lib64)
-libdir = sp.Popen \
-  ('ABI=$(portageq envvar ABI); echo /usr/`portageq envvar LIBDIR_$ABI`/', \
-  stdout=sp.PIPE, shell=True).communicate()[0].strip()
-    
-# Figures directory
-figdir = figdirb + time.strftime('%Y-%m-%d')
-if os.path.exists(figdir):
-    n = 1
-    while True:
-        figdir = figdirb + time.strftime('%Y-%m-%d') + "_%i"%n
-        if not os.path.exists(figdir):
-            os.makedirs(figdir)
-            break
-        n += 1
-else:
-    os.makedirs(figdir)
-  
-# Logs directory
-logdir = "/var/log/benchmarks/" + time.strftime('%Y-%m-%d')
-if os.path.exists(logdir):
-    n = 1
-    while True:
-        logdir = "/var/log/benchmarks/" + time.strftime('%Y-%m-%d') + "_%i"%n
-        if not os.path.exists(logdir):
-            os.makedirs(logdir)
-            break
-        n += 1
-else:
-    os.makedirs(logdir)
 
 def print_usage():
-    print "Usage: benchmarks [blas|cblas|lapack] file args"   
-      
-class _Print:
-    def __init__(self, maxlevel=10):
-        self._level = 0
-        self._maxlevel = maxlevel
-    
-    def __call__(self, arg):
-        if self._level > self._maxlevel:
-            return
-        if self._level <= 0:
-            print str(arg)
-            return
-        print (self._level-1)*"  " + "-- " + str(arg)
-        
-    def up(self, n=1):
-        self._level = max(self._level-n, 0)
-    
-    def down(self, n=1):
-        self._level = max(self._level+n, 0)
-Print = _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
+
 
 # Import the desired module or print help and exit
 try:
     testsfname = os.path.abspath(sys.argv[2])
-    os.chdir(scriptdir)
+    os.chdir(cfg.scriptdir)
     tmp = __import__(sys.argv[1], fromlist = ['Module'])
-    mod = tmp.Module(Print, libdir, sys.argv[3:])
+    mod = 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))
     
-    pkgdir = pjoin(pkgsdir, name)
-    root = pjoin(rootsdir, name)
-    tlogdir = pjoin(logdir, name)
+    pkgdir = pjoin(cfg.pkgsdir, name)
+    root = pjoin(cfg.rootsdir, name)
+    tlogdir = pjoin(cfg.logdir, name)
     os.path.exists(tlogdir) or os.makedirs(tlogdir)
     
     # Emerge package
@@ -227,27 +171,26 @@ for tn,(name,test) in enumerate(tests.items(),1):
         Print.down()
         
         # Run the test suite
-        testdir = os.path.join(testsdir, name, impl)
-        test['results'][impl] = \
-          mod.run_test(root, impl, testdir, env=test['env'], logdir=tlogdir)
+        testdir = os.path.join(cfg.testsdir, name, impl)
+        t = mod.getTest(root, impl, testdir, logdir=tlogdir)
+        test['results'][impl] = t.run_test()
         Print.up()
             
     Print.up()
     print
     
 
-# Reports will be saved in figdir
+# Reports will be saved in cfg.reportdir
 
 # Results are reordered:
 # results
 # |-(name1, impl1) -> resultobject11
 # |-(name1, impl2) -> resultobject12
-# |-(name2, impl1) -> resultobject21
-os.path.exists(figdir) or os.makedirs(figdir)        
+# |-(name2, impl1) -> resultobject21        
 results = {}
 for (name,test) in tests.items():
     if test.has_key('implementations'):
         for impl in test['implementations']:
             results[(name, impl)] = test['results'][impl]
 
-mod.save_results(results, figdir)
+mod.save_results(results)



             reply	other threads:[~2011-07-04 21:39 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-04 21:38 Andrea Arteaga [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-07-13 16:05 [gentoo-commits] proj/auto-numerical-bench:mid-term commit in: app-benchmarks/autobench/files/python/ Andrea Arteaga
2011-07-13 16:00 ` [gentoo-commits] proj/auto-numerical-bench:master " Andrea Arteaga
2011-07-13 10:01 Andrea Arteaga
2011-07-13  0:01 Andrea Arteaga
2011-07-12 15:08 Andrea Arteaga
2011-07-04 21:38 Andrea Arteaga
2011-07-01 16:06 Andrea Arteaga
2011-07-01 12:28 Andrea Arteaga

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=30b1b4ec2c495adaab4a7c33656ce994a661b4ea.spiros@gentoo \
    --to=andyspiros@gmail.com \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox