Merge branch 'openmp' of ssh://eodev.git.sourceforge.net/gitroot/eodev/eodev into openmp
Conflicts: eo/test/CMakeLists.txt
This commit is contained in:
commit
9635901fc1
15 changed files with 681 additions and 6 deletions
|
|
@ -44,6 +44,12 @@ ENABLE_LANGUAGE(C)
|
||||||
### 2) Include required modules / configuration files
|
### 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(CMakeBackwardCompatibilityCXX)
|
||||||
|
|
||||||
INCLUDE(FindDoxygen)
|
INCLUDE(FindDoxygen)
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,11 @@
|
||||||
#ifndef _apply_h
|
#ifndef _apply_h
|
||||||
#define _apply_h
|
#define _apply_h
|
||||||
|
|
||||||
|
#include <utils/eoParallel.h>
|
||||||
|
#include <utils/eoParser.h>
|
||||||
#include <eoFunctor.h>
|
#include <eoFunctor.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Applies a unary function to a std::vector of things.
|
Applies a unary function to a std::vector of things.
|
||||||
|
|
@ -37,7 +40,71 @@
|
||||||
template <class EOT>
|
template <class EOT>
|
||||||
void apply(eoUF<EOT&, void>& _proc, std::vector<EOT>& _pop)
|
void apply(eoUF<EOT&, void>& _proc, std::vector<EOT>& _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<EOT> which is called in parallel
|
||||||
|
thanks to OpenMP.
|
||||||
|
|
||||||
|
@ingroup Utilities
|
||||||
|
*/
|
||||||
|
template <class EOT>
|
||||||
|
void omp_apply(eoUF<EOT&, void>& _proc, std::vector<EOT>& _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 <class EOT>
|
||||||
|
void omp_dynamic_apply(eoUF<EOT&, void>& _proc, std::vector<EOT>& _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]);
|
_proc(_pop[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@
|
||||||
|
|
||||||
#include <utils/eoParserLogger.h>
|
#include <utils/eoParserLogger.h>
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
#include <utils/eoParallel.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@ SET (EOUTILS_SOURCES eoData.cpp
|
||||||
make_help.cpp
|
make_help.cpp
|
||||||
pipecom.cpp
|
pipecom.cpp
|
||||||
eoLogger.cpp
|
eoLogger.cpp
|
||||||
eoParserLogger.cpp)
|
eoParserLogger.cpp
|
||||||
|
eoParallel.cpp)
|
||||||
|
|
||||||
|
|
||||||
ADD_LIBRARY(eoutils STATIC ${EOUTILS_SOURCES})
|
ADD_LIBRARY(eoutils STATIC ${EOUTILS_SOURCES})
|
||||||
|
|
|
||||||
79
eo/src/utils/eoParallel.cpp
Normal file
79
eo/src/utils/eoParallel.cpp
Normal file
|
|
@ -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 <caner.candan@thalesgroup.com>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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;
|
||||||
80
eo/src/utils/eoParallel.h
Normal file
80
eo/src/utils/eoParallel.h
Normal file
|
|
@ -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 <caner.candan@thalesgroup.com>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @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<bool> _isEnabled;
|
||||||
|
eoValueParam<bool> _isDynamic;
|
||||||
|
eoValueParam<std::string> _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
|
||||||
|
|
@ -61,7 +61,6 @@ eoParameterLoader::~eoParameterLoader()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription,
|
eoParser::eoParser ( unsigned _argc, char **_argv , string _programDescription,
|
||||||
string _lFileParamName, char _shortHand) :
|
string _lFileParamName, char _shortHand) :
|
||||||
programName(_argv[0]),
|
programName(_argv[0]),
|
||||||
|
|
|
||||||
|
|
@ -92,8 +92,6 @@ private :
|
||||||
std::vector<eoParam*> ownedParams;
|
std::vector<eoParam*> ownedParams;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
eoParser: command line parser and configuration file reader
|
eoParser: command line parser and configuration file reader
|
||||||
This class is persistent, so it can be stored and reloaded to restore
|
This class is persistent, so it can be stored and reloaded to restore
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,8 @@ SET (TEST_LIST
|
||||||
t-eoExtendedVelocity
|
t-eoExtendedVelocity
|
||||||
t-eoLogger
|
t-eoLogger
|
||||||
t-eoIQRStat
|
t-eoIQRStat
|
||||||
|
t-eoParallel
|
||||||
|
t-openmp
|
||||||
#t-eoDualFitness
|
#t-eoDualFitness
|
||||||
t-eoParser
|
t-eoParser
|
||||||
)
|
)
|
||||||
|
|
@ -94,6 +96,21 @@ ELSEIF(ENABLE_CMAKE_TESTING)
|
||||||
INSTALL(TARGETS ${test} RUNTIME DESTINATION share/eo/test COMPONENT test)
|
INSTALL(TARGETS ${test} RUNTIME DESTINATION share/eo/test COMPONENT test)
|
||||||
ENDFOREACH (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)
|
ENDIF(ENABLE_MINIMAL_CMAKE_TESTING)
|
||||||
|
|
||||||
######################################################################################
|
######################################################################################
|
||||||
|
|
|
||||||
15
eo/test/boxplot.py
Executable file
15
eo/test/boxplot.py
Executable file
|
|
@ -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()
|
||||||
15
eo/test/boxplot_to_pdf.py
Executable file
15
eo/test/boxplot_to_pdf.py
Executable file
|
|
@ -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 )
|
||||||
15
eo/test/boxplot_to_png.py
Executable file
15
eo/test/boxplot_to_png.py
Executable file
|
|
@ -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' )
|
||||||
46
eo/test/t-eoParallel.cpp
Normal file
46
eo/test/t-eoParallel.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// t-eoParallel.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
#include <es/make_real.h>
|
||||||
|
//#include <apply.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
199
eo/test/t-openmp.cpp
Normal file
199
eo/test/t-openmp.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// t-openmp.cpp
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
#include <utils/eoLogger.h>
|
||||||
|
#include <utils/eoParserLogger.h>
|
||||||
|
|
||||||
|
#include <eo>
|
||||||
|
#include <es/make_real.h>
|
||||||
|
|
||||||
|
#include <apply.h>
|
||||||
|
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
|
#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<double>&)
|
||||||
|
{
|
||||||
|
eoRng myrng( get_rdtsc() );
|
||||||
|
::usleep( myrng.random( 10 ) );
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double measure_apply( size_t p,
|
||||||
|
void (*fct)(eoUF<EOT&, void>&, std::vector<EOT>&),
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
138
eo/test/t-openmp.py
Executable file
138
eo/test/t-openmp.py
Executable file
|
|
@ -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 ###')
|
||||||
Reference in a new issue