diff --git a/eo/CMakeLists.txt b/eo/CMakeLists.txt index ca2f8580..548f1b54 100644 --- a/eo/CMakeLists.txt +++ b/eo/CMakeLists.txt @@ -44,6 +44,12 @@ ENABLE_LANGUAGE(C) ### 2) Include required modules / configuration files ##################################################################################### +FIND_PACKAGE(OpenMP REQUIRED) +IF(OPENMP_FOUND) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +ENDIF() + INCLUDE(CMakeBackwardCompatibilityCXX) INCLUDE(FindDoxygen) diff --git a/eo/src/apply.h b/eo/src/apply.h index 0eb3484e..63044c38 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -26,8 +26,11 @@ #ifndef _apply_h #define _apply_h +#include +#include #include #include +#include /** Applies a unary function to a std::vector of things. @@ -37,7 +40,71 @@ template void apply(eoUF& _proc, std::vector& _pop) { - for (unsigned i = 0; i < _pop.size(); ++i) +#ifdef _OPENMP + + omp_set_num_threads(eo::parallel.nthreads()); + + size_t size = _pop.size(); + + double t1 = omp_get_wtime(); + + if (!eo::parallel.isDynamic()) + { +#pragma omp parallel for if(eo::parallel.isEnabled()) //default(none) shared(_proc, _pop, size) + for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } + } + else + { +#pragma omp parallel for schedule(dynamic) if(eo::parallel.isEnabled()) + //doesnot work with gcc 4.1.2 + //default(none) shared(_proc, _pop, size) + for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } + } + + double t2 = omp_get_wtime(); + + eoLogger log; + log << eo::file(eo::parallel.prefix()) << t2 - t1 << ' '; + +#else // _OPENMP + + for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } + +#endif // !_OPENMP +} + +/** + This is a variant of apply which is called in parallel + thanks to OpenMP. + + @ingroup Utilities +*/ +template +void omp_apply(eoUF& _proc, std::vector& _pop) +{ + size_t size = _pop.size(); +#pragma omp parallel for if(eo::parallel.isEnabled()) + //doesnot work with gcc 4.1.2 + //default(none) shared(_proc, _pop, size) + for (size_t i = 0; i < size; ++i) + { + _proc(_pop[i]); + } +} + +/** + And now we are using the dynamic scheduling. + + @ingroup Utilities +*/ +template +void omp_dynamic_apply(eoUF& _proc, std::vector& _pop) +{ + size_t size = _pop.size(); +#pragma omp parallel for if(eo::parallel.isEnabled()) schedule(dynamic) + //doesnot work with gcc 4.1.2 + //default(none) shared(_proc, _pop, size) + for (size_t i = 0; i < size; ++i) { _proc(_pop[i]); } diff --git a/eo/src/eo b/eo/src/eo index 89ed7da9..18e91d60 100644 --- a/eo/src/eo +++ b/eo/src/eo @@ -201,7 +201,7 @@ #include -//----------------------------------------------------------------------------- +#include #endif diff --git a/eo/src/utils/CMakeLists.txt b/eo/src/utils/CMakeLists.txt index ec70053b..94f994d2 100644 --- a/eo/src/utils/CMakeLists.txt +++ b/eo/src/utils/CMakeLists.txt @@ -27,7 +27,8 @@ SET (EOUTILS_SOURCES eoData.cpp make_help.cpp pipecom.cpp eoLogger.cpp - eoParserLogger.cpp) + eoParserLogger.cpp + eoParallel.cpp) ADD_LIBRARY(eoutils STATIC ${EOUTILS_SOURCES}) diff --git a/eo/src/utils/eoParallel.cpp b/eo/src/utils/eoParallel.cpp new file mode 100644 index 00000000..e267ce7f --- /dev/null +++ b/eo/src/utils/eoParallel.cpp @@ -0,0 +1,79 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +/* + +(c) Thales group, 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Contact: http://eodev.sourceforge.net + +Authors: +Caner Candan + +*/ + +#include "eoParallel.h" + +eoParallel::eoParallel() : + _isEnabled( false, "parallelize-loop", "Enable memory shared parallelization into evaluation's loops", '\0' ), + _isDynamic( false, "parallelize-dynamic", "Enable dynamic memory shared parallelization", '\0' ), + _prefix( "results", "parallelize-prefix", "Here's the prefix filename where the results are going to be stored", '\0' ), + _nthreads( 0, "parallelize-nthreads", "Define the number of threads you want to use, nthreads = 0 means you want to use all threads available", '\0' ) +{} + +std::string eoParallel::className() const +{ + return "eoParallel"; +} + +std::string eoParallel::prefix() const +{ + std::string value( _prefix.value() ); + + if ( _isEnabled.value() ) + { + if ( _isDynamic.value() ) + { + value += "_dynamic.out"; + } + else + { + value += "_parallel.out"; + } + } + else + { + value += "_sequential.out"; + } + + return value; +} + +void eoParallel::_createParameters( eoParser& parser ) +{ + std::string section("Parallelization"); + parser.processParam( _isEnabled, section ); + parser.processParam( _isDynamic, section ); + parser.processParam( _prefix, section ); + parser.processParam( _nthreads, section ); +} + +void make_parallel(eoParser& parser) +{ + eo::parallel._createParameters( parser ); +} + +eoParallel eo::parallel; diff --git a/eo/src/utils/eoParallel.h b/eo/src/utils/eoParallel.h new file mode 100644 index 00000000..2ce9ea47 --- /dev/null +++ b/eo/src/utils/eoParallel.h @@ -0,0 +1,80 @@ +// -*- mode: c++; c-indent-level: 4; c++-member-init-indent: 8; comment-column: 35; -*- + +/* +(c) Thales group, 2010 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; + version 2 of the License. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Contact: http://eodev.sourceforge.net + +Authors: +Caner Candan + +*/ + +/** @defgroup Parallel Parallel + * @ingroup Utilities + @{ +*/ + +#ifndef eoParallel_h +#define eoParallel_h + +#include "eoObject.h" +#include "eoParser.h" + +/** + * eoParallel + * Class providing parameters for parallelization + * Use of a global variable eo::parallel to easily use the parallelization parameters anywhere + */ +class eoParallel : public eoObject +{ +public: + eoParallel(); + + virtual std::string className() const; + + inline bool isEnabled() const { return _isEnabled.value(); } + inline bool isDynamic() const { return _isDynamic.value(); } + + std::string prefix() const; + + inline unsigned int nthreads() const { return _nthreads.value(); } + + friend void make_parallel(eoParser&); + +private: + void _createParameters( eoParser& ); + +private: + eoValueParam _isEnabled; + eoValueParam _isDynamic; + eoValueParam _prefix; +}; + +void make_parallel(eoParser&); + +namespace eo +{ + /** + * parallel is an external global variable defined in order to use where ever you want the parallel parameters + */ + extern eoParallel parallel; +} + +/** @} */ + +#endif // !eoParallel_h diff --git a/eo/src/utils/eoParser.cpp b/eo/src/utils/eoParser.cpp index f6c81f14..23970023 100644 --- a/eo/src/utils/eoParser.cpp +++ b/eo/src/utils/eoParser.cpp @@ -61,7 +61,6 @@ eoParameterLoader::~eoParameterLoader() } } - eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription, string _lFileParamName, char _shortHand) : programName(_argv[0]), diff --git a/eo/src/utils/eoParser.h b/eo/src/utils/eoParser.h index bb8e5811..a96ec1be 100644 --- a/eo/src/utils/eoParser.h +++ b/eo/src/utils/eoParser.h @@ -92,8 +92,6 @@ private : std::vector ownedParams; }; - - /** eoParser: command line parser and configuration file reader This class is persistent, so it can be stored and reloaded to restore diff --git a/eo/test/CMakeLists.txt b/eo/test/CMakeLists.txt index f4ed9854..4e68b02a 100644 --- a/eo/test/CMakeLists.txt +++ b/eo/test/CMakeLists.txt @@ -65,6 +65,8 @@ SET (TEST_LIST t-eoExtendedVelocity t-eoLogger t-eoIQRStat + t-eoParallel + t-openmp #t-eoDualFitness t-eoParser ) @@ -94,6 +96,21 @@ ELSEIF(ENABLE_CMAKE_TESTING) INSTALL(TARGETS ${test} RUNTIME DESTINATION share/eo/test COMPONENT test) ENDFOREACH (test) + SET(RESOURCES + boxplot.py + boxplot_to_png.py + boxplot_to_pdf.py + t-openmp.py + ) + + FOREACH(file ${RESOURCES}) + EXECUTE_PROCESS( + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${CMAKE_CURRENT_SOURCE_DIR}/${file} + ${CMAKE_CURRENT_BINARY_DIR}/${file} + ) + ENDFOREACH(file) + ENDIF(ENABLE_MINIMAL_CMAKE_TESTING) ###################################################################################### diff --git a/eo/test/boxplot.py b/eo/test/boxplot.py new file mode 100755 index 00000000..bf6e84b5 --- /dev/null +++ b/eo/test/boxplot.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import pylab +import sys + +if __name__ == '__main__': + if len(sys.argv) < 2: + print 'Usage: boxplot.py [Results files, ...]' + sys.exit() + + for i in range(1, len(sys.argv)): + pylab.boxplot( [ [ float(value) for value in line.split() ] for line in open( sys.argv[i] ).readlines() ] ) + + pylab.xlabel('iterations') + pylab.show() diff --git a/eo/test/boxplot_to_pdf.py b/eo/test/boxplot_to_pdf.py new file mode 100755 index 00000000..f29edeb2 --- /dev/null +++ b/eo/test/boxplot_to_pdf.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import pylab +import sys + +if __name__ == '__main__': + if len(sys.argv) < 3: + print 'Usage: boxplot_to_pdf.py [Results files, ...] [output file in .pdf]' + sys.exit() + + for i in range(1, len(sys.argv) - 1): + pylab.boxplot( [ [ float(value) for value in line.split() ] for line in open( sys.argv[i] ).readlines() ] ) + + pylab.xlabel('iterations') + pylab.savefig( sys.argv[ len(sys.argv) - 1 ], format='pdf', transparent=True ) diff --git a/eo/test/boxplot_to_png.py b/eo/test/boxplot_to_png.py new file mode 100755 index 00000000..17fb35bc --- /dev/null +++ b/eo/test/boxplot_to_png.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import pylab +import sys + +if __name__ == '__main__': + if len(sys.argv) < 3: + print 'Usage: boxplot_to_png.py [Results files, ...] [output file in .png]' + sys.exit() + + for i in range(1, len(sys.argv) - 1): + pylab.boxplot( [ [ float(value) for value in line.split() ] for line in open( sys.argv[i] ).readlines() ] ) + + pylab.xlabel('iterations') + pylab.savefig( sys.argv[ len(sys.argv) - 1 ], format='png', transparent=True, papertype='a0' ) diff --git a/eo/test/t-eoParallel.cpp b/eo/test/t-eoParallel.cpp new file mode 100644 index 00000000..055f4598 --- /dev/null +++ b/eo/test/t-eoParallel.cpp @@ -0,0 +1,46 @@ +//----------------------------------------------------------------------------- +// t-eoParallel.cpp +//----------------------------------------------------------------------------- + +#include +#include +//#include +#include "real_value.h" + +//----------------------------------------------------------------------------- + +typedef eoReal< eoMinimizingFitness > EOT; + +int main(int ac, char** av) +{ + eoParser parser(ac, av); + + unsigned int popSize = parser.getORcreateParam((unsigned int)100, "popSize", "Population Size", 'P', "Evolution Engine").value(); + unsigned int dimSize = parser.getORcreateParam((unsigned int)10, "dimSize", "Dimension Size", 'd', "Evolution Engine").value(); + + uint32_t seedParam = parser.getORcreateParam((uint32_t)0, "seed", "Random number seed", 0).value(); + if (seedParam == 0) { seedParam = time(0); } + + make_parallel(parser); + make_help(parser); + + rng.reseed( seedParam ); + + eoUniformGenerator< double > gen(-5, 5); + eoInitFixedLength< EOT > init( dimSize, gen ); + + eoEvalFuncPtr< EOT, double, const std::vector< double >& > mainEval( real_value ); + eoEvalFuncCounter< EOT > eval( mainEval ); + + eoPop< EOT > pop( popSize, init ); + + //apply< EOT >( eval, pop ); + eoPopLoopEval< EOT > popEval( eval ); + popEval( pop, pop ); + + eo::log << eo::quiet << "DONE!" << std::endl; + + return 0; +} + +//----------------------------------------------------------------------------- diff --git a/eo/test/t-openmp.cpp b/eo/test/t-openmp.cpp new file mode 100644 index 00000000..325cb653 --- /dev/null +++ b/eo/test/t-openmp.cpp @@ -0,0 +1,199 @@ +//----------------------------------------------------------------------------- +// t-openmp.cpp +//----------------------------------------------------------------------------- + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include + +#include "real_value.h" + +//----------------------------------------------------------------------------- + +typedef eoReal< eoMinimizingFitness > EOT; + +//----------------------------------------------------------------------------- + +inline uint32_t get_rdtsc() { __asm__ ("xor %eax, %eax; cpuid; rdtsc"); } + +double variable_time_function(const std::vector&) +{ + eoRng myrng( get_rdtsc() ); + ::usleep( myrng.random( 10 ) ); + return 0.0; +} + +double measure_apply( size_t p, + void (*fct)(eoUF&, std::vector&), + eoInitFixedLength< EOT >& init, + eoEvalFuncCounter< EOT >& eval ) +{ + eoPop< EOT > pop( p, init ); + double t1 = omp_get_wtime(); + fct( eval, pop ); + double t2 = omp_get_wtime(); + return t2 - t1; +} + +void measure( size_t p, + eoInitFixedLength< EOT >& init, + eoEvalFuncCounter< EOT >& eval, + std::ofstream& speedupFile, + std::ofstream& efficiencyFile, + std::ofstream& dynamicityFile, + size_t nbtask ) +{ + // sequential scope + double Ts = measure_apply( p, apply< EOT >, init, eval ); + // parallel scope + double Tp = measure_apply( p, omp_apply< EOT >, init, eval ); + // parallel scope dynamic + double Tpd = measure_apply( p, omp_dynamic_apply< EOT >, init, eval ); + + double speedup = Ts / Tp; + + if ( speedup > nbtask ) { return; } + + double efficiency = speedup / nbtask; + + speedupFile << speedup << ' '; + efficiencyFile << efficiency << ' '; + + eo::log << eo::debug; + eo::log << "Ts = " << Ts << std::endl; + eo::log << "Tp = " << Tp << std::endl; + eo::log << "S_p = " << speedup << std::endl; + eo::log << "E_p = " << efficiency << std::endl; + + double dynamicity = Tp / Tpd; + + if ( dynamicity > nbtask ) { return; } + + eo::log << "Tpd = " << Tpd << std::endl; + eo::log << "D_p = " << dynamicity << std::endl; + + dynamicityFile << dynamicity << ' '; +} + + +int main(int ac, char** av) +{ + eoParserLogger parser(ac, av); + + unsigned int popMin = parser.getORcreateParam((unsigned int)1, "popMin", "Population Min", 'p', "Evolution Engine").value(); + unsigned int popStep = parser.getORcreateParam((unsigned int)1, "popStep", "Population Step", 0, "Evolution Engine").value(); + unsigned int popMax = parser.getORcreateParam((unsigned int)100, "popMax", "Population Max", 'P', "Evolution Engine").value(); + + unsigned int dimMin = parser.getORcreateParam((unsigned int)1, "dimMin", "Dimension Min", 'd', "Evolution Engine").value(); + unsigned int dimStep = parser.getORcreateParam((unsigned int)1, "dimStep", "Dimension Step", 0, "Evolution Engine").value(); + unsigned int dimMax = parser.getORcreateParam((unsigned int)100, "dimMax", "Dimension Max", 'D', "Evolution Engine").value(); + + unsigned int nRun = parser.getORcreateParam((unsigned int)100, "nRun", "Number of runs", 'r', "Evolution Engine").value(); + + std::string fileNamesPrefix = parser.getORcreateParam(std::string(""), "fileNamesPrefix", "Prefix of all results files name", 'H', "Results").value(); + + std::string speedupFileName = parser.getORcreateParam(std::string("speedup"), "speedupFileName", "Speedup file name", 0, "Results").value(); + std::string efficiencyFileName = parser.getORcreateParam(std::string("efficiency"), "efficiencyFileName", "Efficiency file name", 0, "Results").value(); + std::string dynamicityFileName = parser.getORcreateParam(std::string("dynamicity"), "dynamicityFileName", "Dynamicity file name", 0, "Results").value(); + + uint32_t seedParam = parser.getORcreateParam((uint32_t)0, "seed", "Random number seed", 0).value(); + if (seedParam == 0) { seedParam = time(0); } + + unsigned int measureConstTime = parser.getORcreateParam((unsigned int)1, "measureConstTime", "Toggle measure of constant time", 'C', "Results").value(); + unsigned int measureVarTime = parser.getORcreateParam((unsigned int)1, "measureVarTime", "Toggle measure of variable time", 'V', "Results").value(); + + if (parser.userNeedsHelp()) + { + parser.printHelp(std::cout); + exit(1); + } + + make_help(parser); + make_verbose(parser); + + rng.reseed( seedParam ); + + eoEvalFuncPtr< EOT, double, const std::vector< double >& > mainEval( real_value ); + eoEvalFuncCounter< EOT > eval( mainEval ); + + eoEvalFuncPtr< EOT, double, const std::vector< double >& > mainEval_variable( variable_time_function ); + eoEvalFuncCounter< EOT > eval_variable( mainEval_variable ); + + eoUniformGenerator< double > gen(-5, 5); + + std::ostringstream params; + params << "_p" << popMin << "_pS" << popStep << "_P" << popMax + << "_d" << dimMin << "_dS" << dimStep << "_D" << dimMax + << "_r" << nRun << "_s" << seedParam; + + std::ofstream speedupFile( std::string( fileNamesPrefix + speedupFileName + params.str() ).c_str() ); + std::ofstream efficiencyFile( std::string( fileNamesPrefix + efficiencyFileName + params.str() ).c_str() ); + std::ofstream dynamicityFile( std::string( fileNamesPrefix + dynamicityFileName + params.str() ).c_str() ); + + std::ofstream speedupFile_variable( std::string( fileNamesPrefix + "variable_" + speedupFileName + params.str() ).c_str() ); + std::ofstream efficiencyFile_variable( std::string( fileNamesPrefix + "variable_" + efficiencyFileName + params.str() ).c_str() ); + std::ofstream dynamicityFile_variable( std::string( fileNamesPrefix + "variable_" + dynamicityFileName + params.str() ).c_str() ); + + size_t nbtask = 1; +#pragma omp parallel + { + nbtask = omp_get_num_threads(); + } + + eo::log << eo::logging << "Nb task: " << nbtask << std::endl; + + for ( size_t p = popMin; p <= popMax; p += popStep ) + { + for ( size_t d = dimMin; d <= dimMax; d += dimStep ) + { + eo::log << eo::logging << p << 'x' << d << std::endl; + + for ( size_t r = 0; r < nRun; ++r ) + { + eoInitFixedLength< EOT > init( d, gen ); + + // for constant time measure + if ( measureConstTime == 1 ) + { + measure( p, init, eval, speedupFile, efficiencyFile, dynamicityFile, nbtask ); + } + + // for variable time measure + if ( measureVarTime == 1 ) + { + measure( p, init, eval_variable, speedupFile_variable, efficiencyFile_variable, dynamicityFile_variable, nbtask ); + } + } // end of runs + + if ( measureConstTime == 1 ) + { + speedupFile << std::endl; + efficiencyFile << std::endl; + dynamicityFile << std::endl; + } + + if ( measureVarTime == 1 ) + { + speedupFile_variable << std::endl; + efficiencyFile_variable << std::endl; + dynamicityFile_variable << std::endl; + } + + } // end of dimension + + } // end of population + + return 0; +} + +//----------------------------------------------------------------------------- diff --git a/eo/test/t-openmp.py b/eo/test/t-openmp.py new file mode 100755 index 00000000..ab43bb93 --- /dev/null +++ b/eo/test/t-openmp.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python + +import optparse, logging, sys, os +from datetime import datetime + +LEVELS = {'debug': logging.DEBUG, + 'info': logging.INFO, + 'warning': logging.WARNING, + 'error': logging.ERROR, + 'critical': logging.CRITICAL} + +LOG_DEFAULT_FILENAME='notitle.log' + +RESULT_FILE_FORMAT='%s%s_p%d_pS%d_P%d_d%d_dS%d_D%d_r%d_s%d' + +def parser(parser=optparse.OptionParser()): + # general parameters + parser.add_option('-v', '--verbose', choices=LEVELS.keys(), default='info', help='set a verbose level') + parser.add_option('-f', '--file', help='give an input project filename', default='') + parser.add_option('-o', '--output', help='give an output filename for logging', default=LOG_DEFAULT_FILENAME) + # general parameters ends + + parser.add_option('-r', '--nRun', type='int', default=100, help='how many times you would compute each iteration ?') + parser.add_option('-s', '--seed', type='int', default=1, help='give here a seed value') + parser.add_option('-n', '--nProc', type='int', default=1, help='give a number of processus, this value is multiplied by the measures bounds') + parser.add_option('-F', '--fixedBound', type='int', default=1000, help='give the fixed bound value common for all measures') + + topic = str(datetime.today()) + for char in [' ', ':', '-', '.']: topic = topic.replace(char, '_') + parser.add_option('-t', '--topic', default='openmp_measures_' + topic + '/', help='give here a topic name used to create the folder') + + parser.add_option('-E', '--onlyexecute', action='store_true', default=False, help='used this option if you only want to execute measures without generating images') + parser.add_option('-X', '--onlyprint', action='store_true', default=False, help='used this option if you only want to generate images without executing measures, dont forget to set the good path in using --topic with a "/" at the end') + + parser.add_option('-C', '--onlyConstTime', action='store_true', default=False, help='only measures constant time problem') + parser.add_option('-V', '--onlyVarTime', action='store_true', default=False, help='only measures variable time problem') + + parser.add_option('-m', '--measure', action='append', type='int', help='select all measure you want to produce, by default all are produced') + + options, args = parser.parse_args() + + logger(options.verbose, options.output) + + return options + +def logger(level_name, filename=LOG_DEFAULT_FILENAME): + logging.basicConfig( + level=logging.DEBUG, + format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', + filename=filename, filemode='a' + ) + + console = logging.StreamHandler() + console.setLevel(LEVELS.get(level_name, logging.NOTSET)) + console.setFormatter(logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')) + logging.getLogger('').addHandler(console) + +options = parser() + +if not options.onlyexecute: + import pylab + +def get_boxplot_data( filename ): + try: + f = open( filename ) + return [ [ float(value) for value in line.split() ] for line in f.readlines() ] + except: + raise ValueError('got an issue during the reading of file %s' % filename) + +def do_measure( name, p, ps, P, d, ds, D, r=options.nRun, s=options.seed, v='logging' ): + OPENMP_EXEC_FORMAT='./test/t-openmp -p=%d --popStep=%d -P=%d -d=%d --dimStep=%d -D=%d -r=%d --seed=%d -v=%s -H=%s -C=%d -V=%d' + + pwd = options.topic + name + '_' + cmd = OPENMP_EXEC_FORMAT % (p, ps, P, d, ds, D, r, s, v, pwd, + 0 if options.onlyVarTime else 1, + 0 if options.onlyConstTime else 1) + logging.info( cmd ) + if not options.onlyprint: + os.system( cmd ) + + if not options.onlyexecute: + def generate( filenames ): + for cur in filenames: + filename = RESULT_FILE_FORMAT % (pwd, cur, p, ps, P, d, ds, D, r, s) + pylab.boxplot( get_boxplot_data( filename ) ) + nonzero = lambda x: x if x > 0 else 1 + iters = ( nonzero( P - p ) / ps ) * ( nonzero( D - d ) / ds ) + pylab.xlabel('%d iterations from %d,%d to %d,%d' % ( iters, p, d, P, D) ) + pylab.ylabel('%s - %s' % (cur, name)) + pylab.savefig( filename + '.pdf', format='pdf' ) + pylab.savefig( filename + '.png', format='png' ) + pylab.cla() + pylab.clf() + + if not options.onlyVarTime: + generate( ['speedup', 'efficiency', 'dynamicity'] ) + if not options.onlyConstTime: + generate( ['variable_speedup', 'variable_efficiency', 'variable_dynamicity'] ) + +def main(): + if not options.onlyprint: + logging.info('creates first the new topic repository %s', options.topic) + os.mkdir( options.topic ) + + logging.info('do all tests with r = %d and a common seed value = %d' % (options.nRun, options.seed)) + + logging.info('EA in time O(1) and O(n) - speedup measure Sp, Ep and Dp for P & D') + + n = options.nProc + F = options.fixedBound + + if options.measure is None or 1 in options.measure: + logging.info('(1) measure for all combinaisons of P n D') + do_measure( '1', 1*n, 10*n, 101*n, 1*n, 10*n, 101*n ) + + if options.measure is None or 2 in options.measure: + logging.info('(2) measure for P \in [%d, %d[ with D fixed to %d' % (1*n, 101*n, F)) + do_measure( '2', 1*n, 1*n, 101*n, F, 1, F ) + + if options.measure is None or 3 in options.measure: + logging.info('(3) measure for P \in [%d, %d[ with ps = %d and D fixed to %d' % (1*n, 1001*n, 10*n, F)) + do_measure( '3', 1*n, 10*n, 1001*n, F, 1, F ) + + if options.measure is None or 4 in options.measure: + logging.info('(4) measure for D \in [%d, %d[ with P fixed to %d' % (1*n, 101*n, F)) + do_measure( '4', F, 1, F, 1*n, 1*n, 101*n ) + + if options.measure is None or 5 in options.measure: + logging.info('(5) measure for D \in [%d, %d[ with ds = %d and P fixed to %d' % (1*n, 1001*n, 10*n, F)) + do_measure( '5', F, 1, F, 1*n, 10*n, 1001*n ) + +# when executed, just run main(): +if __name__ == '__main__': + logging.debug('### plotting started ###') + + main() + + logging.debug('### plotting ended ###')