Gentoo Archives: gentoo-commits

From: Andrea Arteaga <andyspiros@×××××.com>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/auto-numerical-bench:master commit in: app-benchmarks/autobench/files/python/
Date: Mon, 04 Jul 2011 21:39:47
Message-Id: 30b1b4ec2c495adaab4a7c33656ce994a661b4ea.spiros@gentoo
1 commit: 30b1b4ec2c495adaab4a7c33656ce994a661b4ea
2 Author: spiros <andyspiros <AT> gmail <DOT> com>
3 AuthorDate: Mon Jul 4 21:38:32 2011 +0000
4 Commit: Andrea Arteaga <andyspiros <AT> gmail <DOT> com>
5 CommitDate: Mon Jul 4 21:38:32 2011 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/auto-numerical-bench.git;a=commit;h=30b1b4ec
7
8 Introduced benchconfig: configuration module; benchutils and
9 benchprint: common utilities. New classes *Test: facilities splitted
10 between Modules and Tests. Unified paths, logs, output.
11
12 ---
13 .../autobench/files/python/basemodule.py | 250 +++++++++++---------
14 .../autobench/files/python/benchconfig.py | 75 ++++++
15 .../autobench/files/python/benchprint.py | 28 +++
16 .../autobench/files/python/benchutils.py | 8 +
17 .../autobench/files/python/blas_accuracy.py | 138 ++++++++---
18 app-benchmarks/autobench/files/python/blasbase.py | 10 +-
19 app-benchmarks/autobench/files/python/btlbase.py | 225 ++++++++----------
20 app-benchmarks/autobench/files/python/lapack.py | 13 +-
21 app-benchmarks/autobench/files/python/main.py | 103 ++-------
22 9 files changed, 494 insertions(+), 356 deletions(-)
23
24 diff --git a/app-benchmarks/autobench/files/python/basemodule.py b/app-benchmarks/autobench/files/python/basemodule.py
25 index 5a35cc7..d84d27b 100644
26 --- a/app-benchmarks/autobench/files/python/basemodule.py
27 +++ b/app-benchmarks/autobench/files/python/basemodule.py
28 @@ -1,8 +1,12 @@
29 from os.path import join as pjoin
30 import subprocess as sp
31 import shlex, os
32 +
33 +import benchconfig as cfg
34 from htmlreport import HTMLreport
35 import basemodule
36 +from benchutils import *
37 +from benchprint import Print
38
39 try:
40 import matplotlib.pyplot as plt
41 @@ -14,12 +18,9 @@ except ImportError:
42 sys.stderr.write('Continue anyway.\n\n')
43 with_images = False
44
45 -run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
46
47 class BaseModule:
48 - def __init__(self, Print, libdir, args):
49 - self.Print = Print
50 - self.libdir = libdir
51 + def __init__(self, args):
52 self.summary = False
53 self.summary_only = False
54
55 @@ -37,119 +38,26 @@ class BaseModule:
56 passargs += [i]
57
58 self._parse_args(passargs)
59 -
60 - # Alternatives-2 version with pkg-config
61 - def _get_flags(self, root, impl, libdir):
62 - while libdir[0] == '/':
63 - libdir = libdir[1:]
64 - # Retrieve pkgconfig settings and map the directories to the new root
65 - path = pjoin(root, "etc/env.d/alternatives", \
66 - self.libname,impl,libdir, "pkgconfig")
67 - cmd = ['pkg-config', '--libs', '--cflags', self.libname]
68 - env = {'PKG_CONFIG_PATH':path}
69 - pkgconf = sp.Popen(cmd, stdout=sp.PIPE, env=env).communicate()[0]
70 - pkgconf = pkgconf.replace('-L/', '-L'+root+'/')
71 - pkgconf = pkgconf.replace('-I/', '-I'+root+'/')
72 - return shlex.split(pkgconf)
73
74 # Alternatives-2 version
75 +
76 def get_impls(self, root):
77 output = sp.Popen(
78 ['eselect', '--no-color', '--brief', self.libname, 'list'],
79 env={'ROOT' : root}, stdout=sp.PIPE).communicate()[0]
80 return output.strip().split('\n')
81 -
82 - # Base version
83 - def _generateResults(self, files):
84 - return dict(zip(self.tests, files))
85 -
86 - def run_test(self, root, impl, testdir, env, logdir):
87 - # Convenient renames and definition of report files
88 - Print = self.Print
89 - name = self.libname
90 - files = [pjoin(testdir,f) for f in self.files]
91 - if self.libdir[0] == '/':
92 - libdir = root+self.libdir
93 - else:
94 - libdir = pjoin(root, self.libdir)
95 -
96 - # Create dir. If all results already exist use them and do not perform
97 - # the tests, otherwise remove every old results.
98 - runtests = False
99 - if os.path.exists(testdir):
100 - runtests = not all([os.path.exists(i) for i in files])
101 - else:
102 - os.makedirs(testdir)
103 - runtests = True
104 -
105 - if not runtests:
106 - Print("Not testing: results exist")
107 - return self._generateResults(files)
108 -
109 - for i in files:
110 - if os.path.exists(i): os.remove(i)
111 -
112 - # Prepare the environment
113 - if env.has_key('LIBRARY_PATH'):
114 - env['LIBRARY_PATH'] = libdir + ":" + env['LIBRARY_PATH']
115 - else:
116 - env['LIBRARY_PATH'] = libdir
117 -
118 - if env.has_key('INCLUDE_PATH'):
119 - env['INCLUDE_PATH'] = \
120 - pjoin(root, "usr/include") + ":" + env['INCLUDE_PATH']
121 - else:
122 - env['INCLUDE_PATH'] = pjoin(root, "usr/include")
123 -
124 - if env.has_key('LD_LIBRARY_PATH'):
125 - env['LD_LIBRARY_PATH'] = \
126 - libdir + ":" + env['LD_LIBRARY_PATH']
127 - else:
128 - env['LD_LIBRARY_PATH'] = libdir
129 -
130 - # Backup the environment
131 - oldenv = {}
132 - for k in env.keys():
133 - oldenv[k] = \
134 - (os.environ.has_key(k) and (os.environ[k],) or (None,))[0]
135 -
136 - # Set the new environment
137 - for k,v in env.items():
138 - os.environ[k] = v
139 -
140 - # Compile test suite
141 - logfile = os.path.join(logdir, name+"_comp.log")
142 - returncode, exe = self._compileTest(logfile=logfile, testdir=testdir, \
143 - root=root, impl=impl, libdir=libdir)
144 - if returncode != 0:
145 - Print("Compilation failed")
146 - Print("See log: " + logfile)
147 - return
148 - Print("Compilation successful")
149 -
150 - # Run test
151 - logfile = pjoin(logdir, name+"_run.log")
152 - retcode = self._executeTest(logfile=logfile, exe=exe, testdir=testdir)
153 - if returncode != 0:
154 - Print("Test failed")
155 - Print("See log: " + logfile)
156 - return
157 - Print("Test successful")
158 -
159 - # Restore the old environment
160 - for k in env.keys():
161 - if oldenv[k] != None:
162 - os.environ[k] = oldenv[k]
163 - elif os.environ.has_key(k):
164 - del os.environ[k]
165 -
166 - # Return
167 - return self._generateResults(files)
168 -
169 +
170 + def getTest(self, root, impl, testdir, logdir):
171 + TestClass = self._testClass()
172 + t = TestClass(root, impl, testdir, logdir)
173 + t.libname = self.libname
174 + t.tests = self.tests
175 + t.files = self.files
176 + return t
177
178 - def save_results(self, results, figdir, plottype='plot'):
179 + def save_results(self, results, plottype='plot'):
180 if not with_images:
181 - self.Print("Report generation skipped - missing libraries")
182 + Print("Report generation skipped - missing libraries")
183 return
184
185 if plottype == 'plot': plotf = plt.plot
186 @@ -165,11 +73,13 @@ class BaseModule:
187 newresults[test] = {}
188 for nameimpl in results:
189 nameimplstr = pjoin(*nameimpl)
190 + if results[nameimpl] == None:
191 + continue
192 resdat = results[nameimpl][test]
193 newresults[test][nameimplstr] = resdat
194
195 # Begin the HTML report
196 - htmlfname = pjoin(figdir, 'index.html')
197 + htmlfname = pjoin(cfg.reportdir, 'index.html')
198 html = HTMLreport(htmlfname)
199
200 # Generate summary - a single image with all plots
201 @@ -185,10 +95,10 @@ class BaseModule:
202 plotf(x,y, label=impl, hold=True)
203 plt.legend(loc='best')
204 plt.grid(True)
205 - fname = pjoin(figdir, 'summary.png')
206 + fname = pjoin(cfg.reportdir, 'summary.png')
207 plt.savefig(fname, format='png')
208 html.addFig("Summary", image=os.path.basename(fname), width='95%')
209 - self.Print('Summary figure saved: ' + fname)
210 + Print('Summary figure saved: ' + fname)
211
212 # Generate plots
213 if not self.summary_only:
214 @@ -199,9 +109,123 @@ class BaseModule:
215 plotf(x,y, label=impl, hold=True)
216 plt.legend(loc='best')
217 plt.grid(True)
218 - fname = pjoin(figdir, test+".png")
219 + fname = pjoin(cfg.reportdir, test+".png")
220 plt.savefig(fname, format='png')
221 html.addFig(test, image=os.path.basename(fname))
222 - self.Print('Figure ' + fname + ' saved')
223 + Print('Figure ' + fname + ' saved')
224
225 html.close()
226 + Print('HTML report generated: ' + htmlfname)
227 +
228 +class CompilationError(Exception):
229 + def __init__(self, logfile):
230 + self.logfile = logfile
231 +
232 +
233 +class BaseTest:
234 + libname = None
235 + tests = None
236 + files = None
237 +
238 + def __init__(self, root, impl, testdir, logdir):
239 + self.root = root
240 + self.impl = impl
241 + self.testdir = testdir
242 + self.logdir = pjoin(logdir, impl)
243 + self.compileenv = {}
244 + self.runenv = {}
245 +
246 + mkdir(self.logdir)
247 +
248 + self.libdir = cfg.libdir
249 + while self.libdir[0] == '/':
250 + self.libdir = self.libdir[1:]
251 + self.libdir = pjoin(self.root, self.libdir)
252 +
253 + # Base version
254 + def _generateResults(self):
255 + return dict(zip(self.tests, self.files))
256 +
257 + # Alternatives-2 version with pkg-config
258 + def _get_flags(self):
259 + libdir = cfg.libdir
260 + while libdir[0] == '/':
261 + libdir = libdir[1:]
262 +
263 + # Retrieve pkgconfig settings and map the directories to the new root
264 + path = pjoin(self.root, "etc/env.d/alternatives", \
265 + self.libname, self.impl, libdir, "pkgconfig")
266 + cmd = ['pkg-config', '--libs', '--cflags', self.libname]
267 + env = {
268 + 'PKG_CONFIG_PATH' : path,
269 + 'PKG_CONFIG_LIBDIR' : '',
270 + 'PKG_CONFIG_SYSROOT_DIR' : self.root
271 + }
272 + proc = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.STDOUT, env=env)
273 + pkgconf = proc.communicate()[0]
274 +
275 + # Write logfile
276 + logfname = pjoin(self.logdir, 'pkgconfig.log')
277 + logfile = file(logfname, 'w')
278 + logfile.write('PKG_CONFIG_PATH='+path + '\n')
279 + logfile.write('PKG_CONFIG_LIBDIR=""' + '\n')
280 + logfile.write('PKG_CONFIG_SYSROOT_DIR='+self.root + '\n')
281 + logfile.write(' '.join(cmd) + '\n')
282 + logfile.write(80*'-' + '\n')
283 + logfile.write(pkgconf)
284 + logfile.close()
285 +
286 + if proc.returncode != 0:
287 + raise CompilationError(logfname)
288 +
289 + return shlex.split(pkgconf)
290 +
291 + def run_test(self):
292 + # Convenient renames and definition of report files
293 + name = self.libname
294 + root = self.root
295 + testdir = self.testdir
296 + self.files = [pjoin(testdir,f) for f in self.files]
297 + env = {} # TODO: remove this
298 + if cfg.libdir[0] == '/':
299 + libdir = root+cfg.libdir
300 + else:
301 + libdir = pjoin(root, cfg.libdir)
302 +
303 + # Create dir. If all results already exist use them and do not perform
304 + # the tests, otherwise remove every old results.
305 + runtests = False
306 + if os.path.exists(testdir):
307 + runtests = not all([os.path.exists(i) for i in self.files])
308 + else:
309 + os.makedirs(testdir)
310 + runtests = True
311 + if not runtests:
312 + Print("Not testing: results exist")
313 + return self._generateResults()
314 + for i in self.files:
315 + if os.path.exists(i): os.remove(i)
316 +
317 + # Compile test suite
318 + try:
319 + returncode, exe, logfile = self._compileTest()
320 + if returncode != 0:
321 + raise CompilationError(logfile)
322 + except CompilationError as e:
323 + Print("Compilation failed")
324 + Print("See log: " + e.logfile)
325 + return
326 + Print("Compilation successful")
327 +
328 + # Run test
329 + logfile = pjoin(self.logdir, name+"_run.log")
330 + retcode = self._executeTest(exe)
331 + if returncode != 0:
332 + Print("Test failed")
333 + Print("See log: " + logfile)
334 + return
335 + Print("Test successful")
336 +
337 + # Return
338 + return self._generateResults()
339 +
340 \ No newline at end of file
341
342 diff --git a/app-benchmarks/autobench/files/python/benchconfig.py b/app-benchmarks/autobench/files/python/benchconfig.py
343 new file mode 100644
344 index 0000000..3b941db
345 --- /dev/null
346 +++ b/app-benchmarks/autobench/files/python/benchconfig.py
347 @@ -0,0 +1,75 @@
348 +import sys, os, time
349 +import subprocess as sp
350 +from benchutils import *
351 +
352 +try:
353 + needsinitialization = not initialized
354 +except NameError:
355 + needsinitialization = True
356 +
357 +
358 +if needsinitialization:
359 + isroot = os.getuid() == 0
360 + modname = sys.argv[1]
361 +
362 + # Script directories
363 + curdir = os.path.abspath('.')
364 + scriptdir = os.path.dirname(os.path.realpath(__file__))
365 + btldir = 'btl'
366 +
367 + # Invariant directories:
368 + # roots, tests
369 + rootsdir = "/var/tmp/benchmarks/roots/"
370 + testsdir = "/var/tmp/benchmarks/tests/"
371 +
372 + # Library directory (lib32 vs. lib64)
373 + libdir = sp.Popen \
374 + ('ABI=$(portageq envvar ABI); echo /usr/`portageq envvar LIBDIR_$ABI`/', \
375 + stdout=sp.PIPE, shell=True).communicate()[0].strip()
376 +
377 + # Packages directory
378 + if isroot:
379 + pkgsdir = "/var/cache/benchmarks/packages/"
380 + else:
381 + pkgsdir = os.environ['HOME'] + "/.benchmarks/packages/"
382 +
383 + # Report directory
384 + if isroot:
385 + reportdirb = "/var/cache/benchmarks/reports/"
386 + else:
387 + reportdirb = os.environ['HOME'] + "/.benchmarks/reports/"
388 + reportdirb += modname + "_" + time.strftime('%Y-%m-%d')
389 + if os.path.exists(reportdirb):
390 + n = 1
391 + while True:
392 + reportdir = reportdirb + "_%i" % n
393 + if not os.path.exists(reportdir):
394 + break
395 + n += 1
396 + else:
397 + reportdir = reportdirb
398 + del reportdirb
399 +
400 + # Logs directory
401 + logdirb = "/var/log/benchmarks/" + modname + "_" + time.strftime('%Y-%m-%d')
402 + if os.path.exists(logdirb):
403 + n = 1
404 + while True:
405 + logdir = logdirb + "_%i"%n
406 + if not os.path.exists(logdir):
407 + break
408 + n += 1
409 + else:
410 + logdir = logdirb
411 + del logdirb
412 +
413 +def makedirs():
414 + mkdir(rootsdir)
415 + mkdir(testsdir)
416 + mkdir(pkgsdir)
417 + mkdir(reportdir)
418 + mkdir(logdir)
419 +
420 +
421 +
422 +inizialized = True
423 \ No newline at end of file
424
425 diff --git a/app-benchmarks/autobench/files/python/benchprint.py b/app-benchmarks/autobench/files/python/benchprint.py
426 new file mode 100644
427 index 0000000..b91da66
428 --- /dev/null
429 +++ b/app-benchmarks/autobench/files/python/benchprint.py
430 @@ -0,0 +1,28 @@
431 +try:
432 + needsinitialization = not initialized
433 +except NameError:
434 + needsinitialization = True
435 +
436 +
437 +if needsinitialization:
438 + class _Print:
439 + def __init__(self, maxlevel=10):
440 + self._level = 0
441 + self._maxlevel = maxlevel
442 +
443 + def __call__(self, arg):
444 + if self._level > self._maxlevel:
445 + return
446 + if self._level <= 0:
447 + print str(arg)
448 + return
449 + print (self._level-1)*" " + "-- " + str(arg)
450 +
451 + def up(self, n=1):
452 + self._level = max(self._level-n, 0)
453 +
454 + def down(self, n=1):
455 + self._level = max(self._level+n, 0)
456 + Print = _Print(3)
457 +
458 +initialized = True
459 \ No newline at end of file
460
461 diff --git a/app-benchmarks/autobench/files/python/benchutils.py b/app-benchmarks/autobench/files/python/benchutils.py
462 new file mode 100644
463 index 0000000..824d441
464 --- /dev/null
465 +++ b/app-benchmarks/autobench/files/python/benchutils.py
466 @@ -0,0 +1,8 @@
467 +import os
468 +import subprocess as sp
469 +
470 +def mkdir(dir):
471 + if not os.path.exists(dir):
472 + os.makedirs(dir)
473 +
474 +run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
475 \ No newline at end of file
476
477 diff --git a/app-benchmarks/autobench/files/python/blas_accuracy.py b/app-benchmarks/autobench/files/python/blas_accuracy.py
478 index edbf343..890aa1e 100644
479 --- a/app-benchmarks/autobench/files/python/blas_accuracy.py
480 +++ b/app-benchmarks/autobench/files/python/blas_accuracy.py
481 @@ -1,20 +1,12 @@
482 -from os.path import join as pjoin
483 import subprocess as sp
484 import shlex, os
485 +from os.path import join as pjoin
486 +
487 +from benchutils import *
488 +from benchprint import Print
489 from htmlreport import HTMLreport
490 import basemodule
491 -
492 -try:
493 - import matplotlib.pyplot as plt
494 - import numpy as np
495 - with_images = True
496 -except ImportError:
497 - sys.stderr.write('Error: matplotlib and numpy are needed' + \
498 - 'in order to generate the reports!\n')
499 - sys.stderr.write('Continue anyway.\n\n')
500 - with_images = False
501 -
502 -run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
503 +import benchconfig as cfg
504
505 class Module(basemodule.BaseModule):
506
507 @@ -39,27 +31,101 @@ class Module(basemodule.BaseModule):
508 self.tests = self.avail
509
510 # Generate list of dat (result) files, relative to the testdir
511 - self.files = [pjoin('accuracy_%s_%s.dat' % (op, name)) \
512 + self.files = [pjoin('accuracy_%s_%s.dat' % (op, self.libname)) \
513 for op in self.tests]
514
515 - def _compileTest(self, logfile, testdir, root, impl, *args, **kwargs):
516 - exe = pjoin(testdir, 'test')
517 + @staticmethod
518 + def _testClass():
519 + return BLAS_accuracyTest
520 +
521 +
522 + def save_results(self, results):
523 + basemodule.BaseModule.save_results(self, results, 'loglog')
524 +
525 +class BLAS_accuracyTest(basemodule.BaseTest):
526 +
527 + compileenv = {}
528 + runenv = {}
529 +
530 + def _compileTest(self):
531 + self.compileenv = {}
532 +
533 + # Flags and envvars lists
534 + includes = [pjoin(self.root, 'usr/include')]
535 + libraries = []
536 + libdirs = [self.libdir]
537 + defines = ['NDEBUG']
538 + flags = []
539 +
540 + ## Interpret flags
541 + for flag in self._get_flags() + \
542 + shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()):
543 + flag = flag.strip()
544 + if flag[:2] == '-l':
545 + libraries.append(flag[2:])
546 + elif flag[:2] == '-L':
547 + libdirs.append(flag[2:])
548 + elif flag[:2] == '-I':
549 + includes.append(flag[2:])
550 + else:
551 + flags.append(flag)
552 +
553 + # Set compile environment
554 + self.compileenv['INCLUDE_PATH'] = ':'.join(includes)
555 + self.compileenv['LIBRARY_PATH'] = ':'.join(libdirs)
556 + self.compileenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
557 + self.runenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
558 +
559 + exe = pjoin(self.testdir, "test")
560 source = "accuracy/main_blas.cpp"
561 - flags = self._get_flags(root, impl, self.libdir)
562 - cxxflags = run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()
563 +
564 + # Retrieve compiler
565 cxx = 'g++'
566 - cmd = [cxx, '-o', exe, source] + flags + shlex.split(cxxflags)
567 - proc = sp.Popen(cmd, stdout=file(logfile, 'w'), stderr=sp.STDOUT)
568 + cxx_portage = run_cmd(['portageq', 'envvar', 'CXX']).strip()
569 + if cxx_portage != '':
570 + cxx = cxx_portage
571 + if os.environ.has_key('CXX'):
572 + cxx = os.environ['CXX']
573 +
574 + # Form command line arguments
575 + args = [cxx, source, '-o', exe]
576 + args += ['-I'+I for I in includes]
577 + args += ['-l'+l for l in libraries]
578 + args += ['-L'+L for L in libdirs]
579 + args += ['-D'+D for D in defines]
580 + args += flags
581 +
582 + # Open logfile or redirect to PIPE
583 + logfile = file(pjoin(self.logdir, "compile.log"), 'w')
584 + logfile.write(' '.join([n+'='+v for n,v in self.compileenv.items()]))
585 + logfile.write(' ' + ' '.join(args) + '\n' + 80*'-' + '\n')
586 + logfile.flush()
587 +
588 + # Execute
589 + proc=sp.Popen(args,stdout=logfile,stderr=sp.STDOUT,env=self.compileenv)
590 proc.wait()
591 - return proc.returncode, exe
592 +
593 + # Close, return
594 + logfile.close()
595 + return proc.returncode, exe, logfile.name
596 +
597
598 - def _executeTest(self, logfile, exe, testdir):
599 - # TODO: control objdump and nm
600 - logfile = file(logfile, 'w')
601 - cmd = [exe] + self.tests
602 - proc = sp.Popen(cmd, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE,
603 - cwd=testdir)
604 - self.Print.down()
605 + def _executeTest(self, exe):
606 + # Log dynamic link
607 + lddlogfile = file(pjoin(self.logdir, 'ldd.log'), 'w')
608 + sp.Popen(['ldd', '-v', exe], stdout=lddlogfile, env=self.runenv).wait()
609 +
610 + # Open pipe
611 + logfile = file(pjoin(self.logdir, 'run.log'), 'w')
612 + args = [exe] + self.tests
613 + logfile.write(' '.join([n+'='+v for n,v in self.runenv.items()]) + ' ')
614 + logfile.write(' '.join(args) + '\n')
615 + logfile.write(80*'-' + '\n')
616 + proc = sp.Popen(args, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE,
617 + env=self.runenv, cwd=self.testdir)
618 +
619 + # Interpret output
620 + Print.down()
621 while True:
622 line = proc.stdout.readline()
623 if not line:
624 @@ -68,18 +134,12 @@ class Module(basemodule.BaseModule):
625 if len(line.strip()) == 0:
626 continue
627 if line[0] != ' ':
628 - self.Print.up()
629 - self.Print(line.strip().split()[-1])
630 - self.Print.down()
631 + Print.up()
632 + Print(line.strip().split()[-1])
633 + Print.down()
634 else:
635 - self.Print(line.strip())
636 - self.Print.up()
637 + Print(line.strip())
638 + Print.up()
639 logfile.close()
640 proc.wait()
641 return proc.returncode
642 -
643 -
644 - def save_results(self, results, figdir):
645 - basemodule.BaseModule.save_results(self, results,figdir, 'loglog')
646 -
647 -
648
649 diff --git a/app-benchmarks/autobench/files/python/blasbase.py b/app-benchmarks/autobench/files/python/blasbase.py
650 index d2e4edd..664d706 100644
651 --- a/app-benchmarks/autobench/files/python/blasbase.py
652 +++ b/app-benchmarks/autobench/files/python/blasbase.py
653 @@ -38,7 +38,13 @@ class BLASBase(btlbase.BTLBase):
654 'trisolve_vector', 'matrix_matrix']
655
656 btlbase.BTLBase._parse_args(self, args)
657 -
658 +
659 + @staticmethod
660 + def _testClass():
661 + return BLASTest
662 +
663 +
664 +class BLASTest(btlbase.BTLTest):
665 @staticmethod
666 def _btl_source():
667 return "libs/BLAS/main.cpp"
668 @@ -48,4 +54,4 @@ class BLASBase(btlbase.BTLBase):
669 return ["libs/BLAS"]
670
671 def _btl_defines(self):
672 - return ["CBLASNAME=" + self.libname, "BLAS_INTERFACE"]
673 + return ["CBLASNAME=" + self.libname, "BLAS_INTERFACE"]
674 \ No newline at end of file
675
676 diff --git a/app-benchmarks/autobench/files/python/btlbase.py b/app-benchmarks/autobench/files/python/btlbase.py
677 index 5e07178..1bcc529 100644
678 --- a/app-benchmarks/autobench/files/python/btlbase.py
679 +++ b/app-benchmarks/autobench/files/python/btlbase.py
680 @@ -1,99 +1,12 @@
681 import sys, os, shlex
682 -import commands as cmd
683 import subprocess as sp
684 from os.path import join as pjoin
685 +
686 +from benchutils import *
687 +from benchprint import Print
688 from htmlreport import HTMLreport
689 import basemodule
690 -
691 -try:
692 - import matplotlib.pyplot as plt
693 - import numpy as np
694 - with_images = True
695 -except ImportError:
696 - sys.stderr.write('Error: matplotlib and numpy are needed' + \
697 - 'in order to generate the reports!\n')
698 - sys.stderr.write('Continue anyway.\n\n')
699 - with_images = False
700 -
701 -run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
702 -
703 -def btlcompile(exe, source, btldir, includes, defines, libs, libdirs, other, \
704 - logfile=None):
705 - """
706 - Helper function that compiles a C++ source based on btl. The function
707 - sets the compiler flags that are needed by btl (include directives, link
708 - with rt,...). More options are accepted as arguments:
709 -
710 - exe: the generated executable
711 -
712 - source: the C++ source
713 -
714 - btldir: the base directory of the btl sources
715 -
716 - includes: an iterable containing the include directories (without -I)
717 -
718 - defines: an iterable of strings with define directives (without -D). In case
719 - of key-value pairs, the equal sign and the value have to be in the same
720 - string as the key: ['NDEBUG', 'FOO=BAR'] is transormed to
721 - '-DNDEBUD -DFOO=BAR'
722 -
723 - libs: the libraries to link against (without -l)
724 -
725 - libdirs: the directories where the libraries are seeked (without -L)
726 -
727 - other: an iterable with compiler flags
728 -
729 - logfile: the path of the file where the log is saved. The directory must
730 - exist. If None, no log is generated.
731 - """
732 -
733 - # Compile flags
734 - incs = (
735 - "%s/actions" % btldir,
736 - "%s/generic_bench" % btldir,
737 - "%s/generic_bench/utils" % btldir,
738 - "%s/libs/STL" % btldir
739 - ) + tuple(includes)
740 - incs = ['-I'+i for i in incs]
741 -
742 - defs = ['-D'+d for d in ["NDEBUG"] + defines]
743 -
744 - libs = ['-l'+l for l in ["rt"] + libs]
745 -
746 - libdirs = ['-L'+L for L in libdirs]
747 -
748 - cxxflags = shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip())
749 -
750 - otherfl = other
751 -
752 - # Retrieve compiler
753 - cxx = 'g++'
754 - cxx_portage = run_cmd(['portageq', 'envvar', 'CXX']).strip()
755 - if cxx_portage != '':
756 - cxx = cxx_portage
757 - if os.environ.has_key('CXX'):
758 - cxx = os.environ['CXX']
759 -
760 - # Compile command
761 - cl = [cxx, '-o', exe, source]+incs+defs+libs+libdirs+cxxflags+other
762 -
763 - # Open logfile or redirect to PIPE
764 - if logfile is None:
765 - fout = sp.PIPE
766 - else:
767 - fout = file(logfile, 'w')
768 - fout.write(str(cl) + "\n" + 80*'-' + "\n")
769 - fout.flush()
770 -
771 - # Execute command
772 - cp = sp.Popen(cl, stdout=fout, stderr=sp.STDOUT)
773 - cp.wait()
774 -
775 - # Close the log file (if any)
776 - if logfile is not None:
777 - fout.close()
778 -
779 - return cp.returncode
780 +import benchconfig as cfg
781
782
783 class BTLBase(basemodule.BaseModule):
784 @@ -103,29 +16,101 @@ class BTLBase(basemodule.BaseModule):
785 self.files = [pjoin('bench_%s_%s.dat' % (op, self.libname)) \
786 for op in self.tests]
787
788 - def _compileTest(self, logfile, testdir, root, impl, libdir, \
789 - *args, **kwargs):
790 - btldir = 'btl/'
791 - exe = pjoin(testdir, "test")
792 - returncode = btlcompile(
793 - exe = exe,
794 - source = pjoin(btldir, self._btl_source()),
795 - btldir = btldir,
796 - includes = [pjoin(btldir, d) for d in self._btl_includes()],
797 - defines = self._btl_defines(),
798 - libs = [],
799 - libdirs = [libdir],
800 - other = self._get_flags(root, impl, self.libdir),
801 - logfile = logfile
802 - )
803 - return returncode, exe
804 -
805 - def _executeTest(self, logfile, exe, testdir):
806 - # TODO: control objdump and nm
807 - logfile = file(logfile, 'w')
808 + def save_results(self, results):
809 + basemodule.BaseModule.save_results(self, results, 'semilogx')
810 +
811 +
812 +class BTLTest(basemodule.BaseTest):
813 +
814 + compileenv = {}
815 + runenv = {}
816 +
817 + def _compileTest(self):
818 + self.compileenv = {}
819 +
820 + # Includes
821 + includes = [pjoin(cfg.btldir, i) for i in \
822 + ('actions', 'generic_bench', 'generic_bench/utils', 'libs/STL') + \
823 + tuple(self._btl_includes())] + [pjoin(self.root, 'usr/include')]
824 +
825 + # Libraries
826 + libraries = ['rt']
827 +
828 + # Libdirs
829 + libdirs = [self.libdir]
830 +
831 + # Defines
832 + defines = ['NDEBUG'] + self._btl_defines()
833 +
834 + # Flags
835 + flags = []
836 +
837 + ## Interpret flags
838 + for flag in self._get_flags() + \
839 + shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()):
840 + flag = flag.strip()
841 + if flag[:2] == '-l':
842 + libraries.append(flag[2:])
843 + elif flag[:2] == '-L':
844 + libdirs.append(flag[2:])
845 + elif flag[:2] == '-I':
846 + includes.append(flag[2:])
847 + else:
848 + flags.append(flag)
849 +
850 + # Set compile environment
851 + self.compileenv['INCLUDE_PATH'] = ':'.join(includes)
852 + self.compileenv['LIBRARY_PATH'] = ':'.join(libdirs)
853 + self.compileenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
854 + self.runenv['LD_LIBRARY_PATH'] = ':'.join(libdirs)
855 +
856 + exe = pjoin(self.testdir, "test")
857 +
858 + # Retrieve compiler
859 + cxx = 'g++'
860 + cxx_portage = run_cmd(['portageq', 'envvar', 'CXX']).strip()
861 + if cxx_portage != '':
862 + cxx = cxx_portage
863 + if os.environ.has_key('CXX'):
864 + cxx = os.environ['CXX']
865 +
866 + # Form command line arguments
867 + args = [cxx, pjoin(cfg.btldir, self._btl_source()), '-o', exe]
868 + args += ['-I'+I for I in includes]
869 + args += ['-l'+l for l in libraries]
870 + args += ['-L'+L for L in libdirs]
871 + args += ['-D'+D for D in defines]
872 + args += flags
873 +
874 + # Open logfile or redirect to PIPE
875 + logfile = file(pjoin(self.logdir, "compile.log"), 'w')
876 + logfile.write(' '.join([n+'='+v for n,v in self.compileenv.items()]))
877 + logfile.write(' ' + ' '.join(args) + '\n' + 80*'-' + '\n')
878 + logfile.flush()
879 +
880 + # Execute
881 + proc=sp.Popen(args,stdout=logfile,stderr=sp.STDOUT,env=self.compileenv)
882 + proc.wait()
883 +
884 + # Close, return
885 + logfile.close()
886 + return proc.returncode, exe, logfile.name
887 +
888 + def _executeTest(self, exe):
889 + # Log dynamic link
890 + lddlogfile = file(pjoin(self.logdir, 'ldd.log'), 'w')
891 + sp.Popen(['ldd', '-v', exe], stdout=lddlogfile, env=self.runenv).wait()
892 +
893 + # Open pipe
894 + logfile = file(pjoin(self.logdir, 'btlrun.log'), 'w')
895 args = [exe] + self.tests
896 + logfile.write(' '.join([n+'='+v for n,v in self.runenv.items()]) + ' ')
897 + logfile.write(' '.join(args) + '\n')
898 + logfile.write(80*'-' + '\n')
899 proc = sp.Popen(args, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE,
900 - cwd = testdir)
901 + env=self.runenv, cwd=self.testdir)
902 +
903 + # Interpret output
904 while True:
905 # Each operation test begins with a line on stderr
906 errline = proc.stderr.readline()
907 @@ -134,18 +119,18 @@ class BTLBase(basemodule.BaseModule):
908 logfile.write(errline)
909 resfile = errline.split()[-1]
910 testname = resfile[6:-5-len(self.libname)]
911 - self.Print(resfile)
912 + Print(resfile)
913
914 # 100 different sizes for each operation test
915 - self.Print.down()
916 + Print.down()
917 for i in xrange(100):
918 outline = proc.stdout.readline()
919 + # If the line is void, something gone wrong
920 + if not outline:
921 + return 1
922 logfile.write(outline)
923 - self.Print(outline.strip())
924 - self.Print.up()
925 + Print(outline.strip())
926 + Print.up()
927 logfile.close()
928 proc.wait()
929 - return proc.returncode
930 -
931 - def save_results(self, results, figdir):
932 - basemodule.BaseModule.save_results(self, results,figdir, 'semilogx')
933 + return proc.returncode
934 \ No newline at end of file
935
936 diff --git a/app-benchmarks/autobench/files/python/lapack.py b/app-benchmarks/autobench/files/python/lapack.py
937 index 136d837..e618380 100644
938 --- a/app-benchmarks/autobench/files/python/lapack.py
939 +++ b/app-benchmarks/autobench/files/python/lapack.py
940 @@ -27,6 +27,13 @@ class Module(btlbase.BTLBase):
941 btlbase.BTLBase._parse_args(self, args)
942
943 @staticmethod
944 + def _testClass():
945 + return LapackTest
946 +
947 +
948 +
949 +class LapackTest(btlbase.BTLTest):
950 + @staticmethod
951 def _btl_source():
952 return "libs/LAPACK/main.cpp"
953
954 @@ -34,5 +41,7 @@ class Module(btlbase.BTLBase):
955 def _btl_includes():
956 return ["libs/BLAS", "libs/LAPACK"]
957
958 - def _btl_defines(self):
959 - return ["LAPACKNAME=" + self.libname]
960 + @staticmethod
961 + def _btl_defines():
962 + return ["LAPACKNAME=lapack"]
963 +
964 \ No newline at end of file
965
966 diff --git a/app-benchmarks/autobench/files/python/main.py b/app-benchmarks/autobench/files/python/main.py
967 index 3a02791..79b41e9 100644
968 --- a/app-benchmarks/autobench/files/python/main.py
969 +++ b/app-benchmarks/autobench/files/python/main.py
970 @@ -1,85 +1,29 @@
971 #! /usr/bin/env python2
972
973 -import os, sys, shlex
974 +import os, sys, shlex, time
975 from os.path import join as pjoin
976 -from PortageUtils import *
977 import subprocess as sp
978 -import time
979 -
980 -# Retrieve relevant files/directories
981 -# TODO: use external config module to share these variables (or use environ?)
982 -curdir = os.path.abspath('.')
983 -scriptdir = os.path.dirname(os.path.realpath(__file__))
984 -rootsdir = "/var/tmp/benchmarks/roots/"
985 -testsdir = "/var/tmp/benchmarks/tests/"
986 -if os.getuid() == 0:
987 - pkgsdir = "/var/cache/benchmarks/packages/"
988 - figdirb = "/var/cache/benchmarks/results/"
989 -else:
990 - pkgsdir = os.environ['HOME'] + "/.benchmarks/packages/"
991 - figdirb = os.environ['HOME'] + "/.benchmarks/results/"
992 -
993 -# Library directory (lib32 vs. lib64)
994 -libdir = sp.Popen \
995 - ('ABI=$(portageq envvar ABI); echo /usr/`portageq envvar LIBDIR_$ABI`/', \
996 - stdout=sp.PIPE, shell=True).communicate()[0].strip()
997 -
998 -# Figures directory
999 -figdir = figdirb + time.strftime('%Y-%m-%d')
1000 -if os.path.exists(figdir):
1001 - n = 1
1002 - while True:
1003 - figdir = figdirb + time.strftime('%Y-%m-%d') + "_%i"%n
1004 - if not os.path.exists(figdir):
1005 - os.makedirs(figdir)
1006 - break
1007 - n += 1
1008 -else:
1009 - os.makedirs(figdir)
1010 -
1011 -# Logs directory
1012 -logdir = "/var/log/benchmarks/" + time.strftime('%Y-%m-%d')
1013 -if os.path.exists(logdir):
1014 - n = 1
1015 - while True:
1016 - logdir = "/var/log/benchmarks/" + time.strftime('%Y-%m-%d') + "_%i"%n
1017 - if not os.path.exists(logdir):
1018 - os.makedirs(logdir)
1019 - break
1020 - n += 1
1021 -else:
1022 - os.makedirs(logdir)
1023
1024 def print_usage():
1025 - print "Usage: benchmarks [blas|cblas|lapack] file args"
1026 -
1027 -class _Print:
1028 - def __init__(self, maxlevel=10):
1029 - self._level = 0
1030 - self._maxlevel = maxlevel
1031 -
1032 - def __call__(self, arg):
1033 - if self._level > self._maxlevel:
1034 - return
1035 - if self._level <= 0:
1036 - print str(arg)
1037 - return
1038 - print (self._level-1)*" " + "-- " + str(arg)
1039 -
1040 - def up(self, n=1):
1041 - self._level = max(self._level-n, 0)
1042 -
1043 - def down(self, n=1):
1044 - self._level = max(self._level+n, 0)
1045 -Print = _Print(3)
1046 + print "Usage: benchmarks [blas|cblas|lapack] file args"
1047 +
1048 +if len(sys.argv) < 3:
1049 + print_usage()
1050 + exit(1)
1051 +
1052 +from PortageUtils import *
1053 +import benchconfig as cfg
1054 +from benchprint import Print
1055 +
1056
1057 # Import the desired module or print help and exit
1058 try:
1059 testsfname = os.path.abspath(sys.argv[2])
1060 - os.chdir(scriptdir)
1061 + os.chdir(cfg.scriptdir)
1062 tmp = __import__(sys.argv[1], fromlist = ['Module'])
1063 - mod = tmp.Module(Print, libdir, sys.argv[3:])
1064 + mod = tmp.Module(sys.argv[3:])
1065 del tmp
1066 + cfg.makedirs()
1067 except ImportError, IndexError:
1068 print_usage()
1069 exit(1)
1070 @@ -177,9 +121,9 @@ print
1071 for tn,(name,test) in enumerate(tests.items(),1):
1072 Print("BEGIN TEST %i - %s" % (tn, name))
1073
1074 - pkgdir = pjoin(pkgsdir, name)
1075 - root = pjoin(rootsdir, name)
1076 - tlogdir = pjoin(logdir, name)
1077 + pkgdir = pjoin(cfg.pkgsdir, name)
1078 + root = pjoin(cfg.rootsdir, name)
1079 + tlogdir = pjoin(cfg.logdir, name)
1080 os.path.exists(tlogdir) or os.makedirs(tlogdir)
1081
1082 # Emerge package
1083 @@ -227,27 +171,26 @@ for tn,(name,test) in enumerate(tests.items(),1):
1084 Print.down()
1085
1086 # Run the test suite
1087 - testdir = os.path.join(testsdir, name, impl)
1088 - test['results'][impl] = \
1089 - mod.run_test(root, impl, testdir, env=test['env'], logdir=tlogdir)
1090 + testdir = os.path.join(cfg.testsdir, name, impl)
1091 + t = mod.getTest(root, impl, testdir, logdir=tlogdir)
1092 + test['results'][impl] = t.run_test()
1093 Print.up()
1094
1095 Print.up()
1096 print
1097
1098
1099 -# Reports will be saved in figdir
1100 +# Reports will be saved in cfg.reportdir
1101
1102 # Results are reordered:
1103 # results
1104 # |-(name1, impl1) -> resultobject11
1105 # |-(name1, impl2) -> resultobject12
1106 -# |-(name2, impl1) -> resultobject21
1107 -os.path.exists(figdir) or os.makedirs(figdir)
1108 +# |-(name2, impl1) -> resultobject21
1109 results = {}
1110 for (name,test) in tests.items():
1111 if test.has_key('implementations'):
1112 for impl in test['implementations']:
1113 results[(name, impl)] = test['results'][impl]
1114
1115 -mod.save_results(results, figdir)
1116 +mod.save_results(results)