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: Sun, 03 Jul 2011 20:05:27
Message-Id: 5fb81447de9eac0011f18fbfa2713ad1291c9d9e.spiros@gentoo
1 commit: 5fb81447de9eac0011f18fbfa2713ad1291c9d9e
2 Author: spiros <andyspiros <AT> gmail <DOT> com>
3 AuthorDate: Sun Jul 3 16:25:13 2011 +0000
4 Commit: Andrea Arteaga <andyspiros <AT> gmail <DOT> com>
5 CommitDate: Sun Jul 3 16:25:13 2011 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/auto-numerical-bench.git;a=commit;h=5fb81447
7
8 Added accuracy for BLAS. Many bugfix.
9
10 ---
11 .../autobench/files/python/accuracy/main_blas.cpp | 217 ++++++++++++++++++++
12 app-benchmarks/autobench/files/python/blas.py | 69 +------
13 .../autobench/files/python/blas_accuracy.py | 216 +++++++++++++++++++
14 .../files/python/{blas.py => blasbase.py} | 23 +-
15 app-benchmarks/autobench/files/python/btlbase.py | 80 +++++---
16 app-benchmarks/autobench/files/python/cblas.py | 69 +------
17 app-benchmarks/autobench/files/python/main.py | 8 +-
18 7 files changed, 506 insertions(+), 176 deletions(-)
19
20 diff --git a/app-benchmarks/autobench/files/python/accuracy/main_blas.cpp b/app-benchmarks/autobench/files/python/accuracy/main_blas.cpp
21 new file mode 100644
22 index 0000000..4a7a735
23 --- /dev/null
24 +++ b/app-benchmarks/autobench/files/python/accuracy/main_blas.cpp
25 @@ -0,0 +1,217 @@
26 +#include <iostream>
27 +#include <fstream>
28 +#include <sstream>
29 +#include <string>
30 +#include <vector>
31 +#include <cmath>
32 +#include <cstdlib>
33 +
34 +#define ADD_
35 +extern "C" {
36 + void daxpy_(const int*, const double*, const double*, const int*, double*, const int*);
37 + void dgemv_(const char*, const int*, const int*, const double*, const double*, const int*, const double*, const int*, const double*, double*, const int*);
38 + void dtrsv_(const char*, const char*, const char*, const int*, const double*, const int*, double*, const int*);
39 + void dgemm_(const char*, const char*, const int*, const int*, const int*, const double*, const double*, const int*, const double*, const int*, const double*, double*, const int*);
40 + double dnrm2_(const int*, const double*, const int*);
41 +}
42 +
43 +using namespace std;
44 +
45 +template<typename T>
46 +void print_array(const int& N, const T* array) {
47 + for (const T *p = array, *e = array+N; p != e; ++p)
48 + cout << *p << " ";
49 +}
50 +
51 +template<typename T>
52 +void print_matrix(const int& rows, const int& cols, const T* matrix) {
53 + for (int row = 0; row < rows; ++row) {
54 + for (int col = 0; col < cols; ++col)
55 + cout << *(matrix + rows*col + row) << " ";
56 + cout << "\n";
57 + }
58 +}
59 +
60 +template<typename T>
61 +vector<T> logspace(const T& min, const T& max, const unsigned& N)
62 +{
63 + vector<T> result;
64 + result.reserve(N);
65 +
66 + const double emin = log(static_cast<double>(min)), emax = log(static_cast<double>(max));
67 + double e, r = (emax-emin)/(N-1);
68 + for (unsigned i = 0; i < N; ++i) {
69 + e = emin + i*r;
70 + result.push_back(static_cast<T>(exp(e)));
71 + }
72 +
73 + return result;
74 +}
75 +
76 +double axpy_test(const int& size)
77 +{
78 + // Set up
79 + const int ONE = 1;
80 + const double alpha = 1./3.;
81 + double *x = new double[size], *y = new double[size];
82 + for (int i = 1; i <= size; ++i) {
83 + x[i-1] = 10. / i;
84 + y[i-1] = -10./(3. * i);
85 + }
86 +
87 + // Execute
88 + daxpy_(&size, &alpha, x, &ONE, y, &ONE);
89 +
90 + // Compute the error
91 + double error = dnrm2_(&size, y, &ONE);
92 +
93 + delete[] x; delete[] y;
94 + return error;
95 +}
96 +
97 +double matrix_vector_test(const int& size)
98 +{
99 + // Set up
100 + const int ONE = 1;
101 + char TRANS = 'N';
102 + const double alpha = 1./size, beta = 1.;
103 + double *A = new double[size*size], *x = new double[size], *y = new double[size];
104 + for (int i = 1; i <= size; ++i) {
105 + x[i-1] = i;
106 + y[i-1] = -i;
107 + for (int j = 1; j <= size; ++j) {
108 + *(A+i-1+(j-1)*size) = static_cast<double>(i)/j;
109 + }
110 + }
111 +
112 + // Execute
113 + dgemv_(&TRANS, &size, &size, &alpha, A, &size, x, &ONE, &beta, y, &ONE);
114 +
115 + // Compute the error
116 + double error = dnrm2_(&size, y, &ONE);
117 +
118 + delete[] A; delete[] x; delete[] y;
119 + return error;
120 +}
121 +
122 +double trisolve_vector_test(const int& size)
123 +{
124 + // Set up
125 + const int ONE = 1;
126 + char UPLO = 'U', TRANS = 'N', DIAG = 'U';
127 + double *A = new double[size*size], *x = new double[size+1], *y = new double[size];
128 + const double alpha = 1.;
129 + x[size] = 0.;
130 + for (int i = 1; i <= size; ++i) {
131 + x[size-i] = x[size-i+1] + 1./i;
132 + y[i-1] = -1.;
133 + for (int j = i; j <= size; ++j) {
134 + *(A+i-1+(j-1)*size) = 1. / (j-i+1);
135 + }
136 + }
137 +
138 + // Execute
139 + dtrsv_(&UPLO, &TRANS, &DIAG, &size, A, &size, x, &ONE);
140 + daxpy_(&size, &alpha, x, &ONE, y, &ONE);
141 + double error = dnrm2_(&size, y, &ONE);
142 +
143 + delete[] A; delete[] x; delete[] y;
144 + return error;
145 +}
146 +
147 +double matrix_matrix_test(const int& size)
148 +{
149 + // rand48 initialization
150 + srand48(5);
151 +
152 + // sigma = SUM[k=1..size](k)
153 + double sigma = 0;
154 + for (int i = 1; i <= size; ++i)
155 + sigma += i;
156 +
157 + // Set up
158 + const int ONE = 1;
159 + char TRANS = 'N';
160 + const double alpha = drand48(), beta = -2. * alpha * sigma;
161 + const int size2 = size*size;
162 + double *A = new double[size2], *B = new double[size2], *C = new double[size2];
163 +
164 + for (int i = 1; i <= size; ++i)
165 + for (int j = 1; j <= size; ++j) {
166 + *(A+i-1+size*(j-1)) = static_cast<double>(j)/i;
167 + *(B+i-1+size*(j-1)) = j;
168 + *(C+i-1+size*(j-1)) = static_cast<double>(j)/(2.*i);
169 + }
170 +
171 + // Execute
172 + dgemm_(&TRANS, &TRANS, &size, &size, &size, &alpha, A, &size, B, &size, &beta, C, &size);
173 + double error = dnrm2_(&size2, C, &ONE);
174 +
175 + delete[] A; delete[] B; delete[] C;
176 + return error;
177 +}
178 +
179 +template<typename T>
180 +void test(T t, const int& min, const int& max, const unsigned& N, const string& name)
181 +{
182 + ostringstream fname;
183 + ofstream fout;
184 + double result;
185 + int N_;
186 +
187 + fname << "accuracy_" << name << "_blas.dat";
188 + fout.open(fname.str().c_str());
189 + cout << name << " test -- " << fname.str() << endl;
190 + vector<int> axpy_sizes = logspace(min, max, N);
191 + N_ = 0;
192 + for (vector<int>::const_reverse_iterator i = axpy_sizes.rbegin(), e = axpy_sizes.rend(); i!=e; ++i) {
193 + result = t(*i);
194 + fout << *i << " " << result << endl;
195 + cout << " size: " << *i << " " << result << " (" << ++N_ << "/100)" << endl;
196 + }
197 + fout.close();
198 + cout << "\n";
199 +}
200 +
201 +int main()
202 +{
203 + bool
204 + axpy=false, axpby=false, rot=false,
205 + matrix_vector=false, atv=false, symv=false, syr2=false, ger=false, trisolve_vector=false,
206 + matrix_matrix=false, aat=false, trisolve_matrix=false, trmm=false
207 + ;
208 +
209 +
210 + for (int i = 1; i < argv; ++i) {
211 + std::string arg = argc[i];
212 + if (arg == "axpy") axpy = true;
213 + else if (arg == "axpby") axpby = true;
214 + else if (arg == "rot") rot = true;
215 + else if (arg == "matrix_vector") matrix_vector = true;
216 + else if (arg == "atv") atv = true;
217 + else if (arg == "symv") symv = true;
218 + else if (arg == "syr2") syr2 = true;
219 + else if (arg == "ger") ger = true;
220 + else if (arg == "trisolve_vector") trisolve_vector = true;
221 + else if (arg == "matrix_matrix") matrix_matrix = true;
222 + else if (arg == "aat") aat = true;
223 + else if (arg == "trisolve_matrix") trisolve_matrix = true;
224 + else if (arg == "trmm") trmm = true;
225 +
226 +
227 + /* AXPY test */
228 + if (axpy)
229 + test(axpy_test, 1, 1000000, 100, "axpy");
230 +
231 + if (matrix_vector)
232 + test(matrix_vector_test, 1, 3000, 100, "matrix_vector");
233 +
234 + if (trisolve_vector)
235 + test(trisolve_vector_test, 1, 3000, 100, "trisolve_vector");
236 +
237 + if (matrix_matrix)
238 + test(matrix_matrix_test, 1, 2000, 100, "matrix_matrix");
239 +
240 + return 0;
241 +
242 +}
243
244 diff --git a/app-benchmarks/autobench/files/python/blas.py b/app-benchmarks/autobench/files/python/blas.py
245 index 52bb221..f6193ef 100644
246 --- a/app-benchmarks/autobench/files/python/blas.py
247 +++ b/app-benchmarks/autobench/files/python/blas.py
248 @@ -1,69 +1,6 @@
249 -import os, btlbase
250 -import subprocess as sp
251 -import shlex
252 +import blasbase
253
254 -class Module(btlbase.BTLBase):
255 +class Module(blasbase.BLASBase):
256 def _initialize(self):
257 self.libname = "blas"
258 - self.avail1 = ['axpy', 'axpby', 'rot']
259 - self.avail2 = ['matrix_vector','atv','symv','syr2','ger',
260 - 'trisolve_vector']
261 - self.avail3 = ['matrix_matrix', 'aat', 'trisolve_matrix', 'trmm']
262 - self.avail = self.avail1 + self.avail2 + self.avail3
263 -
264 - def _parse_args(self, args):
265 - # Parse arguments
266 - tests = []
267 - for i in args:
268 - if i == '1':
269 - tests += avail1
270 - continue
271 - if i == '2':
272 - tests += avail2
273 - continue
274 - if i == '3':
275 - tests += avail3
276 - continue
277 - if i in self.avail:
278 - tests.append(i)
279 - continue
280 - raise Exception("Argument not recognized: " + i)
281 -
282 - # Sort tests
283 - self.tests = [i for i in self.avail if i in tests]
284 -
285 - # If no test is specified, then choose four standard tests
286 - if len(self.tests) == 0:
287 - self.tests = ['axpy', 'matrix_vector', \
288 - 'trisolve_vector', 'matrix_matrix']
289 -
290 - @staticmethod
291 - def _btl_source():
292 - return "/libs/BLAS/main.cpp"
293 -
294 - @staticmethod
295 - def _btl_includes():
296 - return ["/libs/BLAS"]
297 -
298 - def _btl_defines(self):
299 - return ["CBLASNAME=" + self.libname, "BLAS_INTERFACE"]
300 -
301 - def _get_flags(self, root, impl, libdir):
302 - # Retrieve pkgconfig settings and map the directories to the new root
303 - path = "%s/etc/env.d/alternatives/%s/%s/%s/pkgconfig" % \
304 - (root, self.libname, impl, libdir)
305 - pkgconf = sp.Popen('pkg-config --libs --cflags blas', shell=True, \
306 - stdout=sp.PIPE, env={'PKG_CONFIG_PATH':path}).communicate()[0]
307 - pkgconf = pkgconf.replace('-L/', '-L'+root+'/')
308 - pkgconf = pkgconf.replace('-I/', '-I'+root+'/')
309 - return shlex.split(pkgconf)
310 -
311 -
312 - def get_impls(self, root):
313 - output = sp.Popen(
314 - ['eselect', '--no-color', '--brief', self.libname, 'list'],
315 - env={'ROOT' : root}, stdout=sp.PIPE
316 - ).communicate()[0]
317 - return output.strip().split('\n')
318 -
319 -del btlbase
320 + blasbase.BLASBase._initialize(self)
321 \ No newline at end of file
322
323 diff --git a/app-benchmarks/autobench/files/python/blas_accuracy.py b/app-benchmarks/autobench/files/python/blas_accuracy.py
324 new file mode 100644
325 index 0000000..9e13ed2
326 --- /dev/null
327 +++ b/app-benchmarks/autobench/files/python/blas_accuracy.py
328 @@ -0,0 +1,216 @@
329 +from pprint import pprint
330 +from os.path import join as pjoin
331 +import subprocess as sp
332 +import shlex, os
333 +from htmlreport import HTMLreport
334 +
335 +try:
336 + import matplotlib.pyplot as plt
337 + import numpy as np
338 + with_images = True
339 +except ImportError:
340 + sys.stderr.write('Error: matplotlib and numpy are needed' + \
341 + 'in order to generate the reports!\n')
342 + sys.stderr.write('Continue anyway.\n\n')
343 + with_images = False
344 +
345 +run_cmd = lambda c : sp.Popen(c, stdout=sp.PIPE).communicate()[0]
346 +
347 +class Module:
348 + def __init__(self, Print, libdir, args):
349 + self.Print = Print
350 + self.libdir = libdir
351 + self.summary = False
352 + self.summary_only = False
353 +
354 + self._initialize()
355 +
356 + passargs = []
357 + for i in args:
358 + if i == '-S':
359 + self.summary_only = True
360 + continue
361 + elif i == '-s':
362 + self.summary = True
363 + continue
364 + else:
365 + passargs += [i]
366 +
367 + self._parse_args(passargs)
368 +
369 + def _initialize(self):
370 + self.libname = 'blas'
371 + self.avail=['axpy', 'matrix_vector', 'trisolve_vector', 'matrix_matrix']
372 +
373 + def _parse_args(self, args):
374 + # Parse arguments
375 + tests = []
376 + for i in args:
377 + if i in self.avail:
378 + tests.append(i)
379 + continue
380 + raise Exception("Argument not recognized: " + i)
381 +
382 + # Sort tests
383 + self.tests = [i for i in self.avail if i in tests]
384 +
385 + # If no test is specified, then do everything
386 + if len(self.tests) == 0:
387 + self.tests = self.avail
388 +
389 + def _get_flags(self, root, impl, libdir):
390 + # Retrieve pkgconfig settings and map the directories to the new root
391 + path = pjoin(root, "etc/env.d/alternatives", \
392 + self.libname, impl, libdir, "pkgconfig")
393 + cmd = ['pkg-config', '--libs', '--cflags', self.libname]
394 + env = {'PKG_CONFIG_PATH':path}
395 + pkgconf = sp.Popen(cmd, stdout=sp.PIPE, env=env).communicate()[0]
396 + pkgconf = pkgconf.replace('-L/', '-L'+root+'/')
397 + pkgconf = pkgconf.replace('-I/', '-I'+root+'/')
398 + return shlex.split(pkgconf)
399 +
400 + def get_impls(self, root):
401 + output = sp.Popen(
402 + ['eselect', '--no-color', '--brief', 'blas', 'list'],
403 + env={'ROOT' : root}, stdout=sp.PIPE
404 + ).communicate()[0]
405 + return output.strip().split('\n')
406 +
407 + def run_test(self, root, impl, testdir, env, logdir):
408 + Print = self.Print
409 + libdir = self.libdir
410 + name = self.libname
411 + files = [pjoin(testdir, 'accuracy_%s_%s.dat' % (op, name)) \
412 + for op in self.tests]
413 +
414 + results = {}
415 + for op in self.tests:
416 + results[op] = pjoin(testdir, 'accuracy_%s_%s.dat' % (op, name))
417 +
418 + # Prepare the environment
419 + if env.has_key('LIBRARY_PATH'):
420 + env['LIBRARY_PATH'] = pjoin(root,libdir) + ":" + env['LIBRARY_PATH']
421 + else:
422 + env['LIBRARY_PATH'] = pjoin(root, libdir)
423 +
424 + if env.has_key('INCLUDE_PATH'):
425 + env['INCLUDE_PATH'] = \
426 + pjoin(root, "/usr/include") + ":" + env['INCLUDE_PATH']
427 + else:
428 + env['INCLUDE_PATH'] = pjoin(root, "/usr/include")
429 +
430 + if env.has_key('LD_LIBRARY_PATH'):
431 + env['LD_LIBRARY_PATH'] = \
432 + pjoin(root, libdir) + ":" + env['LD_LIBRARY_PATH']
433 + else:
434 + env['LD_LIBRARY_PATH'] = pjoin(root, libdir)
435 +
436 + # Backup the environment
437 + oldenv = {}
438 + for k in env.keys():
439 + oldenv[k] = \
440 + (os.environ.has_key(k) and (os.environ[k],) or (None,))[0]
441 +
442 + # Set the environment
443 + for k,v in env.items():
444 + os.environ[k] = v
445 +
446 + # Compile test suite
447 + exe = pjoin(testdir, 'test')
448 + source = "accuracy/main_blas.cpp"
449 + flags = self._get_flags(root, impl, libdir)
450 + cxxflags = run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()
451 + cxx = 'g++'
452 + cmd = [cxx, '-o', exe, source] + flags + shlex.split(cxxflags)
453 + logfile = pjoin(logdir, 'compile.log')
454 + p = sp.Popen(cmd, stdout=file(logfile, 'w'), stderr=sp.STDOUT)
455 + p.wait()
456 + if p.returncode != 0:
457 + Print("Compilation failed")
458 + Print("See log: " + logfile)
459 + return
460 + Print("Compilation successful")
461 +
462 + # Run test
463 + logfile = file(pjoin(logdir, name+"_run.log"), 'w')
464 + cmd = [pjoin(testdir,"test")] + self.tests
465 + proc = sp.Popen(cmd, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE,
466 + cwd=testdir)
467 + Print.down()
468 + while True:
469 + line = proc.stdout.readline()
470 + if not line:
471 + break
472 + logfile.write(line)
473 + if len(line.strip()) == 0:
474 + continue
475 + if line[0] != ' ':
476 + Print.up()
477 + Print(line.strip().split()[-1])
478 + Print.down()
479 + else:
480 + Print(line.strip())
481 + Print.up()
482 + logfile.close()
483 + proc.wait()
484 + if proc.returncode != 0:
485 + Print('Test failed')
486 + else:
487 + Print('Test successful')
488 +
489 + return results
490 +
491 +
492 + def save_results(self, results, figdir):
493 + if not with_images:
494 + self.Print("Report generation skipped - missing libraries")
495 + return
496 +
497 + # Re-order the result dictionary
498 + newresults = {}
499 + for test in self.tests:
500 + newresults[test] = {}
501 + for nameimpl in results:
502 + nameimplstr = pjoin(*nameimpl)
503 + resdat = results[nameimpl][test]
504 + newresults[test][nameimplstr] = resdat
505 +
506 + # Begin the HTML report
507 + htmlfname = pjoin(figdir, 'index.html')
508 + html = HTMLreport(htmlfname)
509 +
510 + # Generate summary - a single image with all plots
511 + if self.summary or self.summary_only:
512 + # Save summary figure
513 + sprows = (len(self.tests)+1)/2
514 + plt.figure(figsize=(16,6*sprows), dpi=300)
515 + for i, test in enumerate(self.tests, 1):
516 + plt.subplot(sprows, 2, i)
517 + plt.title(test)
518 + for impl in newresults[test]:
519 + x,y = np.loadtxt(newresults[test][impl], unpack=True)
520 + plt.loglog(x,y, label=impl, hold=True)
521 + plt.legend(loc='best')
522 + plt.grid(True)
523 + fname = pjoin(figdir, 'summary.png')
524 + plt.savefig(fname, format='png')
525 + html.addFig("Summary", image=os.path.basename(fname), width='95%')
526 + self.Print('Summary figure saved: ' + fname)
527 +
528 + # Generate plots
529 + if not self.summary_only:
530 + for test in self.tests:
531 + plt.figure(figsize=(12,9), dpi=300)
532 + for impl in newresults[test]:
533 + x,y = np.loadtxt(newresults[test][impl], unpack=True)
534 + plt.loglog(x,y, label=impl, hold=True)
535 + plt.legend(loc='best')
536 + plt.grid(True)
537 + fname = pjoin(figdir, test+".png")
538 + plt.savefig(fname, format='png')
539 + html.addFig(test, image=os.path.basename(fname))
540 + self.Print('Figure ' + fname + ' saved')
541 +
542 + html.close()
543 +
544 +
545
546 diff --git a/app-benchmarks/autobench/files/python/blas.py b/app-benchmarks/autobench/files/python/blasbase.py
547 similarity index 77%
548 copy from app-benchmarks/autobench/files/python/blas.py
549 copy to app-benchmarks/autobench/files/python/blasbase.py
550 index 52bb221..2ca9070 100644
551 --- a/app-benchmarks/autobench/files/python/blas.py
552 +++ b/app-benchmarks/autobench/files/python/blasbase.py
553 @@ -1,10 +1,10 @@
554 import os, btlbase
555 import subprocess as sp
556 import shlex
557 +from os.path import join as pjoin
558
559 -class Module(btlbase.BTLBase):
560 +class BLASBase(btlbase.BTLBase):
561 def _initialize(self):
562 - self.libname = "blas"
563 self.avail1 = ['axpy', 'axpby', 'rot']
564 self.avail2 = ['matrix_vector','atv','symv','syr2','ger',
565 'trisolve_vector']
566 @@ -16,13 +16,13 @@ class Module(btlbase.BTLBase):
567 tests = []
568 for i in args:
569 if i == '1':
570 - tests += avail1
571 + tests += self.avail1
572 continue
573 if i == '2':
574 - tests += avail2
575 + tests += self.avail2
576 continue
577 if i == '3':
578 - tests += avail3
579 + tests += self.avail3
580 continue
581 if i in self.avail:
582 tests.append(i)
583 @@ -39,21 +39,22 @@ class Module(btlbase.BTLBase):
584
585 @staticmethod
586 def _btl_source():
587 - return "/libs/BLAS/main.cpp"
588 + return "libs/BLAS/main.cpp"
589
590 @staticmethod
591 def _btl_includes():
592 - return ["/libs/BLAS"]
593 + return ["libs/BLAS"]
594
595 def _btl_defines(self):
596 return ["CBLASNAME=" + self.libname, "BLAS_INTERFACE"]
597
598 def _get_flags(self, root, impl, libdir):
599 # Retrieve pkgconfig settings and map the directories to the new root
600 - path = "%s/etc/env.d/alternatives/%s/%s/%s/pkgconfig" % \
601 - (root, self.libname, impl, libdir)
602 - pkgconf = sp.Popen('pkg-config --libs --cflags blas', shell=True, \
603 - stdout=sp.PIPE, env={'PKG_CONFIG_PATH':path}).communicate()[0]
604 + path = pjoin(root, "etc/env.d/alternatives", \
605 + self.libname,impl,libdir, "pkgconfig")
606 + cmd = ['pkg-config', '--libs', '--cflags', self.libname]
607 + env = {'PKG_CONFIG_PATH':path}
608 + pkgconf = sp.Popen(cmd, stdout=sp.PIPE, env=env).communicate()[0]
609 pkgconf = pkgconf.replace('-L/', '-L'+root+'/')
610 pkgconf = pkgconf.replace('-I/', '-I'+root+'/')
611 return shlex.split(pkgconf)
612
613 diff --git a/app-benchmarks/autobench/files/python/btlbase.py b/app-benchmarks/autobench/files/python/btlbase.py
614 index d71650e..1c6f8aa 100644
615 --- a/app-benchmarks/autobench/files/python/btlbase.py
616 +++ b/app-benchmarks/autobench/files/python/btlbase.py
617 @@ -46,40 +46,53 @@ def btlcompile(exe, source, btldir, includes, defines, libs, libdirs, other, \
618 exist. If None, no log is generated.
619 """
620
621 + # Compile flags
622 incs = (
623 "%s/actions" % btldir,
624 "%s/generic_bench" % btldir,
625 "%s/generic_bench/utils" % btldir,
626 "%s/libs/STL" % btldir
627 ) + tuple(includes)
628 - incs = ' '.join(['-I'+i for i in incs])
629 + incs = ['-I'+i for i in incs]
630
631 - defs = ' '.join(['-D'+d for d in ["NDEBUG"] + defines])
632 + defs = ['-D'+d for d in ["NDEBUG"] + defines]
633
634 - libs = ' '.join(['-l'+l for l in ["rt"] + libs])
635 + libs = ['-l'+l for l in ["rt"] + libs]
636
637 - libdirs = ' '.join(['-L'+L for L in libdirs])
638 + libdirs = ['-L'+L for L in libdirs]
639
640 - cxxflags = run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip()
641 + cxxflags = shlex.split(run_cmd(['portageq', 'envvar', 'CXXFLAGS']).strip())
642
643 - otherflags = ' '.join(other)
644 + otherfl = other
645
646 - # TODO: use CXX instead of g++
647 - cl = "g++ -o %s %s %s %s %s %s %s %s" \
648 - % (exe, source, incs, defs, libs, libdirs, cxxflags, otherflags)
649 -
650 + # Retrieve compiler
651 + cxx = 'g++'
652 + cxx_portage = run_cmd(['portageq', 'envvar', 'CXX']).strip()
653 + if cxx_portage != '':
654 + cxx = cxx_portage
655 + if os.environ.has_key('CXX'):
656 + cxx = os.environ['CXX']
657 +
658 + # Compile command
659 + cl = [cxx, '-o', exe, source]+incs+defs+libs+libdirs+cxxflags+other
660 +
661 + # Open logfile or redirect to PIPE
662 if logfile is None:
663 fout = sp.PIPE
664 else:
665 fout = file(logfile, 'w')
666 - fout.write(cl + "\n" + 80*'-' + "\n")
667 + fout.write(str(cl) + "\n" + 80*'-' + "\n")
668 fout.flush()
669 - cl = shlex.split(cl)
670 +
671 + # Execute command
672 cp = sp.Popen(cl, stdout=fout, stderr=sp.STDOUT)
673 - cp.communicate()
674 + cp.wait()
675 +
676 + # Close the log file (if any)
677 if logfile is not None:
678 fout.close()
679 - return (cp.returncode, ' '.join(cl))
680 +
681 + return cp.returncode
682
683
684 class BTLBase:
685 @@ -134,19 +147,21 @@ class BTLBase:
686
687 # Prepare the environment
688 if env.has_key('LIBRARY_PATH'):
689 - env['LIBRARY_PATH'] = root+libdir + ":" + env['LIBRARY_PATH']
690 + env['LIBRARY_PATH'] = pjoin(root,libdir) + ":" + env['LIBRARY_PATH']
691 else:
692 - env['LIBRARY_PATH'] = root+libdir
693 + env['LIBRARY_PATH'] = pjoin(root, libdir)
694
695 if env.has_key('INCLUDE_PATH'):
696 - env['INCLUDE_PATH'] = root+"/usr/include" +":"+ env['INCLUDE_PATH']
697 + env['INCLUDE_PATH'] = \
698 + pjoin(root, "/usr/include") + ":" + env['INCLUDE_PATH']
699 else:
700 - env['INCLUDE_PATH'] = root+"/usr/include"
701 + env['INCLUDE_PATH'] = pjoin(root, "/usr/include")
702
703 if env.has_key('LD_LIBRARY_PATH'):
704 - env['LD_LIBRARY_PATH'] = root+libdir + ":" + env['LD_LIBRARY_PATH']
705 + env['LD_LIBRARY_PATH'] = \
706 + pjoin(root, libdir) + ":" + env['LD_LIBRARY_PATH']
707 else:
708 - env['LD_LIBRARY_PATH'] = root+libdir
709 + env['LD_LIBRARY_PATH'] = pjoin(root, libdir)
710
711 # Backup the environment
712 oldenv = {}
713 @@ -158,15 +173,14 @@ class BTLBase:
714 for k,v in env.items():
715 os.environ[k] = v
716
717 - # Compile
718 - # TODO: use CXX instead of g++
719 + # Compile test suite
720 btldir = 'btl/'
721 logfile = os.path.join(logdir, name+"_comp.log")
722 - returncode, compilecl = btlcompile(
723 - exe = testdir + "/test",
724 - source = btldir + self._btl_source(),
725 + returncode = btlcompile(
726 + exe = pjoin(testdir, "test"),
727 + source = pjoin(btldir, self._btl_source()),
728 btldir = btldir,
729 - includes = [btldir+d for d in self._btl_includes()],
730 + includes = [pjoin(btldir, d) for d in self._btl_includes()],
731 defines = self._btl_defines(),
732 libs = [],
733 libdirs = [root+libdir],
734 @@ -180,29 +194,31 @@ class BTLBase:
735 Print("Compilation successful")
736
737 # Run test
738 - logfile = file(os.path.join(logdir, name+"_run.log"), 'w')
739 - args = [os.path.join(testdir,"test")] + self.tests
740 + logfile = file(pjoin(logdir, name+"_run.log"), 'w')
741 + args = [pjoin(testdir,"test")] + self.tests
742 proc = sp.Popen(args, bufsize=1, stdout=sp.PIPE, stderr=sp.PIPE,
743 cwd = testdir)
744 results = {}
745 while True:
746 + # Each operation test begins with a line on stderr
747 errline = proc.stderr.readline()
748 - logfile.write(errline)
749 if not errline:
750 break
751 + logfile.write(errline)
752 resfile = errline.split()[-1]
753 testname = resfile[6:-5-len(name)]
754 results[testname] = pjoin(testdir, resfile)
755 Print(resfile)
756 +
757 + # 100 different sizes for each operation test
758 Print.down()
759 for i in xrange(100):
760 outline = proc.stdout.readline()
761 logfile.write(outline)
762 Print(outline.rstrip())
763 Print.up()
764 - Print.up()
765 - proc.wait()
766 logfile.close()
767 + proc.wait()
768 if proc.returncode != 0:
769 Print('Test failed')
770 else:
771 @@ -226,7 +242,7 @@ class BTLBase:
772 for test in self.tests:
773 newresults[test] = {}
774 for nameimpl in results:
775 - nameimplstr = "%s/%s" % nameimpl
776 + nameimplstr = pjoin(*nameimpl)
777 resdat = results[nameimpl][test]
778 newresults[test][nameimplstr] = resdat
779
780
781 diff --git a/app-benchmarks/autobench/files/python/cblas.py b/app-benchmarks/autobench/files/python/cblas.py
782 index c3d0342..c78867c 100644
783 --- a/app-benchmarks/autobench/files/python/cblas.py
784 +++ b/app-benchmarks/autobench/files/python/cblas.py
785 @@ -1,69 +1,6 @@
786 -import os, btlbase
787 -import subprocess as sp
788 -import shlex
789 +import blasbase
790
791 -class Module(btlbase.BTLBase):
792 +class Module(blasbase.BLASBase):
793 def _initialize(self):
794 self.libname = "cblas"
795 - self.avail1 = ['axpy', 'axpby', 'rot']
796 - self.avail2 = ['matrix_vector','atv','symv','syr2','ger',
797 - 'trisolve_vector']
798 - self.avail3 = ['matrix_matrix', 'aat', 'trisolve_matrix', 'trmm']
799 - self.avail = self.avail1 + self.avail2 + self.avail3
800 -
801 - def _parse_args(self, args):
802 - # Parse arguments
803 - tests = []
804 - for i in args:
805 - if i == '1':
806 - tests += avail1
807 - continue
808 - if i == '2':
809 - tests += avail2
810 - continue
811 - if i == '3':
812 - tests += avail3
813 - continue
814 - if i in self.avail:
815 - tests.append(i)
816 - continue
817 - raise Exception("Argument not recognized: " + i)
818 -
819 - # Sort tests
820 - self.tests = [i for i in self.avail if i in tests]
821 -
822 - # If no test is specified, then choose four standard tests
823 - if len(self.tests) == 0:
824 - self.tests = ['axpy', 'matrix_vector', \
825 - 'trisolve_vector', 'matrix_matrix']
826 -
827 - @staticmethod
828 - def _btl_source():
829 - return "/libs/BLAS/main.cpp"
830 -
831 - @staticmethod
832 - def _btl_includes():
833 - return ["/libs/BLAS"]
834 -
835 - def _btl_defines(self):
836 - return ["CBLASNAME=" + self.libname, "CBLAS_INTERFACE"]
837 -
838 - def _get_flags(self, root, impl, libdir):
839 - # Retrieve pkgconfig settings and map the directories to the new root
840 - path = "%s/etc/env.d/alternatives/%s/%s/%s/pkgconfig" % \
841 - (root, self.libname, impl, libdir)
842 - pkgconf = sp.Popen('pkg-config --libs --cflags cblas', shell=True, \
843 - stdout=sp.PIPE, env={'PKG_CONFIG_PATH':path}).communicate()[0]
844 - pkgconf = pkgconf.replace('-L/', '-L'+root+'/')
845 - pkgconf = pkgconf.replace('-I/', '-I'+root+'/')
846 - return shlex.split(pkgconf)
847 -
848 -
849 - def get_impls(self, root):
850 - output = sp.Popen(
851 - ['eselect', '--no-color', '--brief', self.libname, 'list'],
852 - env={'ROOT' : root}, stdout=sp.PIPE
853 - ).communicate()[0]
854 - return output.strip().split('\n')
855 -
856 -del btlbase
857 + blasbase.BLASBase._initialize(self)
858 \ No newline at end of file
859
860 diff --git a/app-benchmarks/autobench/files/python/main.py b/app-benchmarks/autobench/files/python/main.py
861 index 991d735..3a02791 100644
862 --- a/app-benchmarks/autobench/files/python/main.py
863 +++ b/app-benchmarks/autobench/files/python/main.py
864 @@ -7,6 +7,7 @@ import subprocess as sp
865 import time
866
867 # Retrieve relevant files/directories
868 +# TODO: use external config module to share these variables (or use environ?)
869 curdir = os.path.abspath('.')
870 scriptdir = os.path.dirname(os.path.realpath(__file__))
871 rootsdir = "/var/tmp/benchmarks/roots/"
872 @@ -236,6 +237,12 @@ for tn,(name,test) in enumerate(tests.items(),1):
873
874
875 # Reports will be saved in figdir
876 +
877 +# Results are reordered:
878 +# results
879 +# |-(name1, impl1) -> resultobject11
880 +# |-(name1, impl2) -> resultobject12
881 +# |-(name2, impl1) -> resultobject21
882 os.path.exists(figdir) or os.makedirs(figdir)
883 results = {}
884 for (name,test) in tests.items():
885 @@ -244,4 +251,3 @@ for (name,test) in tests.items():
886 results[(name, impl)] = test['results'][impl]
887
888 mod.save_results(results, figdir)
889 -