source: XIOS/dev/dev_olga/src/extern/blitz/include/blitz/benchext.cc @ 1022

Last change on this file since 1022 was 1022, checked in by mhnguyen, 7 years ago
File size: 13.6 KB
Line 
1/***************************************************************************
2 * blitz/benchext.cc  Methods for Benchmarking class with external control.
3 *
4 * $Id$
5 *
6 * Copyright (C) 1997-2011 Todd Veldhuizen <tveldhui@acm.org>
7 *
8 * This file is a part of Blitz.
9 *
10 * Blitz is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation, either version 3
13 * of the License, or (at your option) any later version.
14 *
15 * Blitz is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with Blitz.  If not, see <http://www.gnu.org/licenses/>.
22 *
23 * Suggestions:          blitz-devel@lists.sourceforge.net
24 * Bugs:                 blitz-support@lists.sourceforge.net   
25 *
26 * For more information, please see the Blitz++ Home Page:
27 *    https://sourceforge.net/projects/blitz/
28 *
29 ****************************************************************************/
30#ifndef BZ_BENCHEXT_CC
31#define BZ_BENCHEXT_CC
32
33#ifndef BZ_BENCHEXT_H
34 #error <blitz/benchext.cc> must be included via <blitz/benchext.h>
35#endif
36
37//#include <blitz/vector-et.h>
38
39#ifdef BZ_HAVE_STD
40 #include <fstream>
41 #include <string>
42#else
43 #include <fstream.h>
44 #include <string.h>
45#endif
46
47BZ_NAMESPACE(blitz)
48
49template<typename P_parameter>
50BenchmarkExt<P_parameter>::BenchmarkExt(const char* name, 
51    int numImplementations)
52{
53    BZPRECONDITION(numImplementations > 0);
54
55    description_ = name;
56    numImplementations_ = numImplementations;
57
58    implementationDescriptions_.resize(numImplementations);
59    parameterDescription_ = "Vector length";
60   
61    // we don't really know this is the default, do we...
62    setDependentVariable("flops");
63
64    /*
65    // Set up default parameters and iterations
66    setNumParameters(19);
67
68    // NEEDS_WORK: once pow(X,Y) is supported, can just say
69    // parameters_ = pow(10.0, Range(1,20)/4.0);
70   
71    for (unsigned i=0; i < numParameters_; ++i)
72      parameters_(i) = static_cast<P_parameter>(BZ_MATHFN_SCOPE(pow)(10.0, (i+1)/4.0));
73
74    iterations_ = 5.0e+5 / parameters_;
75    flopsPerIteration_ = parameters_;
76    */
77    // Set up initial state
78    state_ = initializing;
79    implementationNumber_ = 0;
80}
81
82template<typename P_parameter>
83BenchmarkExt<P_parameter>::~BenchmarkExt()
84{
85}
86
87template<typename P_parameter>
88void BenchmarkExt<P_parameter>::setNumParameters(int numParameters)
89{
90    //BZPRECONDITION(state_ == initializing);
91
92    numParameters_ = numParameters;
93
94    parameters_.resize(numParameters_);
95    iterations_.resize(numParameters_);
96    flopsPerIteration_.resize(numParameters_);
97
98    // Set up timer and Mflops array
99    times_.resize(numImplementations_, numParameters_);
100    instr_.resize(numImplementations_, numParameters_);
101    flops_.resize(numImplementations_, numParameters_);
102}
103
104template<typename P_parameter>
105void BenchmarkExt<P_parameter>::setParameterVector(Array<P_parameter,1> parms)
106{
107    BZPRECONDITION(state_ == initializing);
108    BZPRECONDITION(parms.size() == parameters_.size());
109
110    parameters_ = parms;
111}
112
113template<typename P_parameter>
114void BenchmarkExt<P_parameter>::setParameterDescription(const char* string)
115{
116    parameterDescription_ = string;
117}
118
119template<typename P_parameter>
120void BenchmarkExt<P_parameter>::setIterations(Array<long,1> iters)
121{
122    BZPRECONDITION(state_ == initializing);
123
124    iterations_ = iters;
125}
126
127template<typename P_parameter>
128void BenchmarkExt<P_parameter>::setOpsPerIteration(Array<double,1> 
129    flopsPerIteration)
130{
131    BZPRECONDITION(flopsPerIteration_.size() == flopsPerIteration.size());
132
133    flopsPerIteration_ = flopsPerIteration;
134}
135
136/** Set the dependent variable of the measurements. If the independent
137    variable is seconds, we output "G<dvar>/s", if it is cycles, we
138    output "<dvar/c". */
139template<typename P_parameter>
140void BenchmarkExt<P_parameter>::setDependentVariable(const char* dvar)
141{
142  BZPRECONDITION(Timer::indep_var()!="");
143
144  if(timer_.indep_var()=="s") {
145    depvar_ = string("G")+dvar+"/s";
146    timerconversion_ = 1./1e9;
147  }
148  else if(timer_.indep_var()=="c") {
149    depvar_ = string(dvar)+"/c";
150    timerconversion_ = 1.;
151  }
152  else {
153    depvar_ = std::string(dvar)+"/"+timer_.indep_var();
154    timerconversion_ = 1;
155    }
156}
157
158template<typename P_parameter>
159void BenchmarkExt<P_parameter>::beginBenchmarking()
160{
161    BZPRECONDITION(state_ == initializing);
162    state_ = benchmarking;
163}
164
165template<typename P_parameter>
166void BenchmarkExt<P_parameter>::beginImplementation(const char* description)
167{
168    // it would really be better if it worked for as many as we give it
169    BZPRECONDITION(implementationNumber_ < numImplementations_);
170    BZPRECONDITION(state_ == benchmarking);
171
172    implementationDescriptions_[implementationNumber_] = description;
173
174    state_ = benchmarkingImplementation;
175    parameterNumber_ = 0;
176}
177
178template<typename P_parameter>
179bool BenchmarkExt<P_parameter>::doneImplementationBenchmark() const
180{
181    BZPRECONDITION(state_ == benchmarkingImplementation);
182    return parameterNumber_ == numParameters_;
183}
184
185template<typename P_parameter>
186const string& BenchmarkExt<P_parameter>::currentImplementation() const
187{
188    BZPRECONDITION(implementationNumber_ < numImplementations_);
189    return implementationDescriptions_[implementationNumber_];
190}
191
192
193template<typename P_parameter>
194P_parameter BenchmarkExt<P_parameter>::getParameter() const
195{
196    BZPRECONDITION(state_ == benchmarkingImplementation);
197    BZPRECONDITION(parameterNumber_ < numParameters_);
198
199    return parameters_(parameterNumber_);
200}
201
202template<typename P_parameter>
203long BenchmarkExt<P_parameter>::getIterations() const
204{
205    BZPRECONDITION(state_ == benchmarkingImplementation);
206    BZPRECONDITION(parameterNumber_ < numParameters_);
207
208    return iterations_(parameterNumber_);
209}
210
211template<typename P_parameter>
212inline void BenchmarkExt<P_parameter>::start()
213{
214    BZPRECONDITION(state_ == benchmarkingImplementation);
215    BZPRECONDITION(parameterNumber_ < numParameters_);
216    state_ = running;
217    timer_.start();
218}
219
220template<typename P_parameter>
221inline void BenchmarkExt<P_parameter>::stop()
222{
223    timer_.stop();
224    BZPRECONDITION(state_ == running);
225    state_ = benchmarkingImplementation;
226
227    times_(int(implementationNumber_), int(parameterNumber_)) = timer_.elapsed();
228    instr_(int(implementationNumber_), int(parameterNumber_)) = timer_.instr();
229    flops_(int(implementationNumber_), int(parameterNumber_)) = timer_.flops();
230    ++parameterNumber_;
231}
232
233template<typename P_parameter>
234inline void BenchmarkExt<P_parameter>::startOverhead()
235{
236    BZPRECONDITION(state_ == benchmarkingImplementation);
237    BZPRECONDITION(parameterNumber_ > 0);
238    BZPRECONDITION(parameterNumber_ <= numParameters_);
239    state_ = runningOverhead;
240    timer_.start();
241}
242
243template<typename P_parameter>
244inline void BenchmarkExt<P_parameter>::stopOverhead()
245{
246    BZPRECONDITION(state_ == runningOverhead);
247    timer_.stop();
248
249    cout << "\ttimer overhead: " <<
250      1.0*timer_.elapsed()/times_(int(implementationNumber_), int(parameterNumber_-1)) << endl;
251
252    times_(int(implementationNumber_), int(parameterNumber_-1)) -= 
253      timer_.elapsed();
254    instr_(int(implementationNumber_), int(parameterNumber_-1)) -= 
255      timer_.instr();
256    flops_(int(implementationNumber_), int(parameterNumber_-1)) -= 
257      timer_.flops();
258
259    if(times_(int(implementationNumber_), int(parameterNumber_-1))<0) {
260      cerr << "\tError: Timer underflow in benchmark " << implementationDescriptions_[implementationNumber_] << " " << parameters_(parameterNumber_-1) << endl;
261      times_(int(implementationNumber_), int(parameterNumber_-1)) = blitz::huge(times_(0,0));
262    }
263    state_ = benchmarkingImplementation;
264}
265
266template<typename P_parameter>
267inline void BenchmarkExt<P_parameter>::skip()
268{
269    BZPRECONDITION(state_ == benchmarkingImplementation);
270    BZPRECONDITION(parameterNumber_ < numParameters_);
271    times_(int(implementationNumber_), int(parameterNumber_)) = blitz::quiet_NaN(double());
272    ++parameterNumber_;
273    state_ = benchmarkingImplementation;
274}
275
276template<typename P_parameter>
277void BenchmarkExt<P_parameter>::endImplementation()
278{
279    BZPRECONDITION(state_ == benchmarkingImplementation);
280    BZPRECONDITION(parameterNumber_ == numParameters_);
281
282    ++implementationNumber_;
283
284    state_ = benchmarking;
285}
286
287template<typename P_parameter>
288void BenchmarkExt<P_parameter>::endBenchmarking()
289{
290    BZPRECONDITION(state_ == benchmarking);
291    BZPRECONDITION(implementationNumber_ == numImplementations_);
292   
293    state_ = done;
294}
295
296template<typename P_parameter>
297double BenchmarkExt<P_parameter>::getMflops(unsigned implementation,
298    unsigned parameterNum) const
299{
300    BZPRECONDITION(state_ == done);
301    BZPRECONDITION(implementation < numImplementations_);
302    BZPRECONDITION(parameterNum < numParameters_);
303    return 1.0*iterations_(parameterNum) * flopsPerIteration_(parameterNum)
304      / times_(int(implementation), int(parameterNum)) * timerconversion_;
305}
306
307template<typename P_parameter>
308double BenchmarkExt<P_parameter>::getinstrperc(int implementation,
309                                               int parameterNum) const
310{
311    BZPRECONDITION(state_ == done);
312    BZPRECONDITION(implementation < numImplementations_);
313    BZPRECONDITION(parameterNum < numParameters_);
314    return 1.0*instr_(implementation,parameterNum)/
315      times_(int(implementation), int(parameterNum));
316}
317template<typename P_parameter>
318double BenchmarkExt<P_parameter>::getflopsperc(int implementation,
319                                               int parameterNum) const
320{
321    BZPRECONDITION(state_ == done);
322    BZPRECONDITION(implementation < numImplementations_);
323    BZPRECONDITION(parameterNum < numParameters_);
324    return 1.0*flops_(implementation,parameterNum)/
325      times_(int(implementation), int(parameterNum));
326}
327
328template<typename P_parameter>
329void BenchmarkExt<P_parameter>::saveMatlabGraph(const char* filename, const char* graphType) const
330{
331    BZPRECONDITION(state_ == done);
332
333    {
334      //ugly but saveMatlabGraph is coded into all benchmarks
335      std::string pyfn(filename);
336      pyfn=pyfn.replace(pyfn.find(".m"),2,std::string(".py"),0,3);
337      savePylabGraph(pyfn.c_str());
338    }
339
340    ofstream ofs(filename);
341     
342    assert(ofs.good());
343
344    ofs << "% This matlab file generated automatically by class Benchmark"
345        << endl << "% of the Blitz++ class library." << endl << endl;
346
347    ofs.setf(ios::scientific);
348
349    // This will be a lot simpler once Matlab-style output formatting
350    // of vectors & matrices is finished.
351
352    // ofs << "parm = " << parameters_ << ";" << endl << endl;
353
354    ofs << "parm = [ ";
355    unsigned i;
356    for (i=0; i < numParameters_; ++i)
357      ofs << setprecision(12) << double(parameters_(i)) << " ";
358    ofs << "]; " << endl << endl;
359
360    ofs << "Mf = [ ";
361    for (i=0; i < numParameters_; ++i)
362    {
363        for (unsigned j=0; j < numImplementations_; ++j)
364        {
365            ofs << setprecision(12) << getMflops(j,i) << " ";
366        }
367        if (i != numParameters_ - 1)
368            ofs << ";" << endl;
369    }
370    ofs << "] ;" << endl << endl;
371
372    ofs << graphType << "(parm,Mf), title('" << description_ << "'), " << endl
373        << "    xlabel('" << parameterDescription_ << "'), "
374        << "ylabel('" << depvar_ << "')\n"
375        << "legend(";
376   
377    for (unsigned j=0; j < numImplementations_; ++j)
378    {
379        ofs << "'" << implementationDescriptions_[j] << "'";
380        if (j != numImplementations_ - 1)
381            ofs << ", ";
382    } 
383
384    ofs << ")" << endl;
385}
386
387
388template<typename P_parameter>
389void BenchmarkExt<P_parameter>::savePylabGraph(const char* filename, const char* graphType) const
390{
391    BZPRECONDITION(state_ == done);
392
393    ofstream ofs(filename);
394     
395    assert(ofs.good());
396
397    ofs << "# This python file generated automatically by class Benchmark\n"
398        << "# of the Blitz++ class library.\n"
399        << "from pylab import *\nfrom numpy import *\n"
400        << "clf()\n";
401
402    ofs.setf(ios::scientific);
403
404    ofs << "legnames=[";
405    for (unsigned j=0; j < numImplementations_; ++j)
406    {
407        ofs << "'" << implementationDescriptions_[j] << "'";
408        if (j != numImplementations_ - 1)
409            ofs << ", ";
410    } 
411
412    ofs << "]\n\nparm = array([ ";
413    unsigned i;
414    for (i=0; i < numParameters_; ++i)
415      ofs << setprecision(12) << double(parameters_(i)) << ", ";
416    ofs << "])\n\n";
417
418    ofs << "Mf = array([[ ";
419    for (i=0; i < numParameters_; ++i)
420    {
421        if(i>0) ofs << ", [ ";
422        for (unsigned j=0; j < numImplementations_; ++j)
423        {
424          ofs << setprecision(12) << getMflops(j,i);
425          if(j<numImplementations_-1) ofs << ", ";
426        }
427        ofs << "]";
428    }
429    ofs << "])" << endl << endl;
430#ifdef BZ_HAVE_LIBPAPI
431    // add i/c and flops counters
432    ofs << "ic = array([[ ";
433    for (i=0; i < numParameters_; ++i)
434    {
435        if(i>0) ofs << ", [ ";
436        for (unsigned j=0; j < numImplementations_; ++j)
437        {
438          ofs << setprecision(12) << getinstrperc(j,i);
439          if(j<numImplementations_-1) ofs << ", ";
440        }
441        ofs << "]";
442    }
443    ofs << "])" << endl << endl;
444    ofs << "fc = array([[ ";
445    for (i=0; i < numParameters_; ++i)
446    {
447        if(i>0) ofs << ", [ ";
448        for (unsigned j=0; j < numImplementations_; ++j)
449        {
450          ofs << setprecision(12) << getflopsperc(j,i);
451          if(j<numImplementations_-1) ofs << ", ";
452        }
453        ofs << "]";
454    }
455    ofs << "])" << endl << endl;
456#endif
457
458    ofs << graphType << "(parm,Mf)\ntitle('" << description_ << "')\n"
459        << "xlabel('" << parameterDescription_ << "')\n"
460        << "ylabel('" << depvar_ << "')\n";
461
462    ofs << "legend(legnames)\n";
463}
464
465BZ_NAMESPACE_END
466
467#endif // BZ_BENCHEXT_CC
Note: See TracBrowser for help on using the repository browser.