diff --git a/eo/src/apply.h b/eo/src/apply.h index b13c434e..939e62bd 100644 --- a/eo/src/apply.h +++ b/eo/src/apply.h @@ -33,12 +33,6 @@ #include #include -# ifdef WITH_MPI -# include -# include -# include -# endif // WITH_MPI - /** Applies a unary function to a std::vector of things. @@ -85,21 +79,6 @@ void apply(eoUF& _proc, std::vector& _pop) #endif // !_OPENMP } -#ifdef WITH_MPI -template -void parallelApply( - std::vector& _pop, - eo::mpi::AssignmentAlgorithm& _algo, - int _masterRank, - eo::mpi::ParallelApplyStore & _store ) -{ - _store.data( _pop ); - _algo.reinit( _pop.size() ); - eo::mpi::ParallelApply job( _algo, _masterRank, _store ); - job.run(); -} -#endif - /** This is a variant of apply which is called in parallel thanks to OpenMP. diff --git a/eo/src/eoEasyEA.h b/eo/src/eoEasyEA.h index 4d74932f..4d9c7b6d 100644 --- a/eo/src/eoEasyEA.h +++ b/eo/src/eoEasyEA.h @@ -37,8 +37,6 @@ #include #include - - template class eoIslandsEasyEA ; template class eoDistEvalEasyEA ; @@ -106,7 +104,7 @@ template class eoEasyEA: public eoAlgo * @brief Ctor allowing to specify which pop eval function we're going to use. * * Ctor taking a breed and merge, an overload of ctor to define an offspring size, and - * the pop eval function used. This allows to precise if we would like to use the + * the pop eval function used. This allows to precise if we would like to use the * parallel evaluation, for instance. */ eoEasyEA( @@ -247,57 +245,43 @@ template class eoEasyEA: public eoAlgo virtual void operator()(eoPop& _pop) { - eo::log << "[EasyEA] Call to operator()" << std::endl; - if (isFirstCall) - { - size_t total_capacity = _pop.capacity() + offspring.capacity(); - _pop.reserve(total_capacity); - offspring.reserve(total_capacity); - isFirstCall = false; - } - - // TODO TODOB delete all log traces - std::cout << "[EasyEA] After is first call." << std::endl; - - eoPop empty_pop; - std::cout << "[EasyEA] After empty_pop." << std::endl; - - popEval(empty_pop, _pop); // A first eval of pop. - std::cout << "[EasyEA] After pop_eval." << std::endl; - - do + if (isFirstCall) { - try + size_t total_capacity = _pop.capacity() + offspring.capacity(); + _pop.reserve(total_capacity); + offspring.reserve(total_capacity); + isFirstCall = false; + } + + eoPop empty_pop; + + do + { + try { - std::cout << "[EasyEA] Beginning try." << std::endl; - unsigned pSize = _pop.size(); - std::cout << "[EasyEA] psize determinated." << std::endl; - offspring.clear(); // new offspring - std::cout << "[EasyEA] offspring cleared." << std::endl; + unsigned pSize = _pop.size(); - breed(_pop, offspring); + offspring.clear(); // new offspring - std::cout << "[EasyEA] After breed, evaluating pop." << std::endl; - popEval(_pop, offspring); // eval of parents + offspring if necessary + breed(_pop, offspring); - std::cout << "[EasyEA] After evaluation, replacing pop." << std::endl; - replace(_pop, offspring); // after replace, the new pop. is in _pop - std::cout << "[EasyEA] After replacing, continuator." << std::endl; + popEval(_pop, offspring); // eval of parents + offspring if necessary - if (pSize > _pop.size()) - throw std::runtime_error("Population shrinking!"); - else if (pSize < _pop.size()) - throw std::runtime_error("Population growing!"); + replace(_pop, offspring); // after replace, the new pop. is in _pop + if (pSize > _pop.size()) + throw std::runtime_error("Population shrinking!"); + else if (pSize < _pop.size()) + throw std::runtime_error("Population growing!"); } - catch (std::exception& e) + catch (std::exception& e) { - std::string s = e.what(); - s.append( " in eoEasyEA"); - throw std::runtime_error( s ); + std::string s = e.what(); + s.append( " in eoEasyEA"); + throw std::runtime_error( s ); } } - while ( continuator( _pop ) ); + while ( continuator( _pop ) ); } protected : diff --git a/eo/src/eoPopEvalFunc.h b/eo/src/eoPopEvalFunc.h index c811e3a5..2cc86807 100644 --- a/eo/src/eoPopEvalFunc.h +++ b/eo/src/eoPopEvalFunc.h @@ -30,6 +30,13 @@ #include #include +# ifdef WITH_MPI +#include +#include +#include +#include +# endif // WITH_MPI + /** eoPopEvalFunc: This abstract class is for GLOBAL evaluators * of a population after variation. * It takes 2 populations (typically the parents and the offspring) @@ -78,12 +85,43 @@ private: }; #ifdef WITH_MPI -// TODO TODOB commenter +/** + * @brief Evaluator of a population of EOT which uses parallelization to evaluate individuals. + * + * This class implements an instance of eoPopEvalFunc that applies a private eoEvalFunc to + * all offspring, but in a parallel way. The original process becomes the central host from a network ("master"), and + * other machines disponible in the MPI network ("slaves") are used as evaluators. Population to evaluate is splitted in + * little packets of individuals, which are sent to the evaluators, that process the effective call to eval. Once all + * the individuals have been evaluated, they are returned to the master. The whole process is entirely invisible to the + * eyes of the user, who just has to launch a certain number of processes in MPI so as to have a result. + * + * The eoEvalFunc is no more directly given, but it is stored in the eo::mpi::ParallelApplyStore, which can be + * instanciated if no one is given at construction. + * + * The use of this class requires the user to have called the eo::mpi::Node::init function, at the beginning of its + * program. + * + * @ingroup Evaluation Parallel + * + * @author Benjamin Bouvier + */ template class eoParallelPopLoopEval : public eoPopEvalFunc { public: - /** Ctor: set value of embedded eoEvalFunc */ + /** + * @brief Constructor which creates the job store for the user. + * + * This constructor is the simplest to use, as it creates the store used by the parallel job, for the user. + * The user just precises the scheduling algorithm, the rank of the master and then gives its eval function and + * the size of a packet (how many individuals should be in a single message to evaluator). + * + * @param _assignAlgo The scheduling algorithm used to give orders to evaluators. + * @param _masterRank The MPI rank of the master. + * @param _eval The evaluation functor used to evaluate each individual in the population. + * @param _packetSize The number of individuals to send in one message to evaluator, and which are evaluated at + * a time. + */ eoParallelPopLoopEval( // Job parameters eo::mpi::AssignmentAlgorithm& _assignAlgo, @@ -94,12 +132,21 @@ class eoParallelPopLoopEval : public eoPopEvalFunc ) : assignAlgo( _assignAlgo ), masterRank( _masterRank ), - needToDeleteStore( true ) + needToDeleteStore( true ) // we used new, we'll have to use delete (RAII) { - // FIXME memory leak because of new. store = new eo::mpi::ParallelApplyStore( _eval, _masterRank, _packetSize ); } + /** + * @brief Constructor which allows the user to customize its job store. + * + * This constructor allows the user to customize the store, for instance by adding wrappers and other + * functionnalities, before using it for the parallelized evaluation. + * + * @param _assignAlgo The scheduling algorithm used to give orders to evaluators. + * @param _masterRank The MPI rank of the master. + * @param _store Pointer to a parallel eval store given by the user. + */ eoParallelPopLoopEval( // Job parameters eo::mpi::AssignmentAlgorithm& _assignAlgo, @@ -109,37 +156,57 @@ class eoParallelPopLoopEval : public eoPopEvalFunc assignAlgo( _assignAlgo ), masterRank( _masterRank ), store( _store ), - needToDeleteStore( false ) + needToDeleteStore( false ) // we haven't used new for creating store, we don't care if we have to delete it (RAII). { // empty } + /** + * @brief Default destructor. Sends a message to all evaluators indicating that the global loop (eoEasyEA, for + * instance) is over. + */ ~eoParallelPopLoopEval() { + // Only the master has to send the termination message if( eo::mpi::Node::comm().rank() == masterRank ) { eo::mpi::EmptyJob job( assignAlgo, masterRank ); job.run(); } + // RAII if( needToDeleteStore ) { delete store; } } - /** Do the job: simple loop over the offspring */ + /** + * @brief Parallel implementation of the operator(). + * + * @param _parents Population of parents (ignored). + * @param _offspring Population of children, which will be evaluated. + */ void operator()( eoPop & _parents, eoPop & _offspring ) { (void)_parents; - parallelApply(_offspring, assignAlgo, masterRank, *store); + // Reinits the store and the scheduling algorithm + store->data( _offspring ); + assignAlgo.reinit( _offspring.size() ); + // Effectively launches the job. + eo::mpi::ParallelApply job( assignAlgo, masterRank, *store ); + job.run(); } private: + // Scheduling algorithm eo::mpi::AssignmentAlgorithm & assignAlgo; + // Master MPI rank int masterRank; + // Store eo::mpi::ParallelApplyStore* store; + // Do we have to delete the store by ourselves ? bool needToDeleteStore; }; #endif diff --git a/eo/src/serial/Array.cpp b/eo/src/serial/Array.cpp index f70b00e8..180aad16 100644 --- a/eo/src/serial/Array.cpp +++ b/eo/src/serial/Array.cpp @@ -1,38 +1,58 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # include "Array.h" namespace eoserial { - -std::ostream& Array::print( std::ostream& out ) const -{ - out << "["; - bool first = true; - for (ArrayChildren::const_iterator it = begin(), - end = this->end(); - it != end; - ++it) + std::ostream& Array::print( std::ostream& out ) const { - if ( first ) + out << "["; + bool first = true; + for (ArrayChildren::const_iterator it = begin(), + end = this->end(); + it != end; + ++it) { - first = false; - } else { - out << ", "; + if ( first ) + { + first = false; + } else { + out << ", "; + } + (*it)->print( out ); } - (*it)->print( out ); + out << "]\n"; + return out; } - out << "]\n"; - return out; -} -Array::~Array() -{ - for (ArrayChildren::iterator it = begin(), - end = this->end(); - it != end; - ++it) + Array::~Array() { - delete *it; + for (ArrayChildren::iterator it = begin(), + end = this->end(); + it != end; + ++it) + { + delete *it; + } } -} } // namespace eoserial diff --git a/eo/src/serial/Array.h b/eo/src/serial/Array.h index 69231980..d453add9 100644 --- a/eo/src/serial/Array.h +++ b/eo/src/serial/Array.h @@ -1,148 +1,169 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_ARRAY_H__ # define __EOSERIAL_ARRAY_H__ # include -# include # include "Entity.h" # include "Serializable.h" - # include "Object.h" -# include "String.h" namespace eoserial { -// Forward declaration for below declarations. -class Array; - -/* - * Declarations of functions present in Utils.h - * These are put here to avoid instead of including the file Utils.h, which would - * cause a circular inclusion. - */ -template< class T > -void unpack( const Array & array, unsigned int index, T & value ); - -void unpackObject( const Array & array, unsigned int index, Persistent & value ); - -template< class Container, template class UnpackAlgorithm > -void unpackArray( const Array & array, unsigned int index, Container & container ); - -/** - * @brief Represents a JSON array. - * - * Wrapper for an array, so as to be used as a JSON object. - */ -class Array : public eoserial::Entity, public std::vector< eoserial::Entity* > -{ -protected: - typedef std::vector< eoserial::Entity* > ArrayChildren; - -public: - /** - * @brief Adds the serializable object as a JSON object. - * @param obj Object which implemnets JsonSerializable. - */ - void push_back( const eoserial::Printable* obj ) - { - ArrayChildren::push_back( obj->pack() ); - } - - /** - * @brief Proxy for vector::push_back. - */ - void push_back( eoserial::Entity* json ) - { - ArrayChildren::push_back( json ); - } - - /** - * @brief Prints the JSON array into the given stream. - * @param out The stream - */ - virtual std::ostream& print( std::ostream& out ) const; - - /** - * @brief Dtor - */ - ~Array(); + // Forward declaration for below declarations. + class Array; /* - * The following parts allows the user to automatically deserialize an eoserial::Array into a - * standard container, by giving the algorithm which will be used to deserialize contained entities. + * Declarations of functions present in Utils.h + * These are put here to avoid instead of including the file Utils.h, which would + * cause a circular inclusion. */ + template< class T > + void unpack( const Array & array, unsigned int index, T & value ); + + void unpackObject( const Array & array, unsigned int index, Persistent & value ); + + template< class Container, template class UnpackAlgorithm > + void unpackArray( const Array & array, unsigned int index, Container & container ); + /** - * @brief Functor which determines how to retrieve the real value contained in a eoserial::Entity at - * a given place. + * @brief Represents a JSON array. * - * It will be applied for each contained variable in the array. + * Wrapper for an array, so as to be used as a JSON object. + * + * @ingroup Serialization */ - template - struct BaseAlgorithm + class Array : public eoserial::Entity, public std::vector< eoserial::Entity* > { - /** - * @brief Main operator. - * - * @param array The eoserial::Array from which we're reading. - * @param i The index of the contained value. - * @param container The standard (STL) container in which we'll push back the read value. - */ - virtual void operator()( const eoserial::Array& array, unsigned int i, Container & container ) const = 0; + protected: + typedef std::vector< eoserial::Entity* > ArrayChildren; + + public: + /** + * @brief Adds the serializable object as a JSON object. + * @param obj Object which implemnets JsonSerializable. + */ + void push_back( const eoserial::Printable* obj ) + { + ArrayChildren::push_back( obj->pack() ); + } + + /** + * @brief Proxy for vector::push_back. + */ + void push_back( eoserial::Entity* json ) + { + ArrayChildren::push_back( json ); + } + + /** + * @brief Prints the JSON array into the given stream. + * @param out The stream + */ + virtual std::ostream& print( std::ostream& out ) const; + + /** + * @brief Dtor + */ + ~Array(); + + /* + * The following parts allows the user to automatically deserialize an eoserial::Array into a + * standard container, by giving the algorithm which will be used to deserialize contained entities. + */ + + /** + * @brief Functor which determines how to retrieve the real value contained in a eoserial::Entity at + * a given place. + * + * It will be applied for each contained variable in the array. + */ + template + struct BaseAlgorithm + { + /** + * @brief Main operator. + * + * @param array The eoserial::Array from which we're reading. + * @param i The index of the contained value. + * @param container The standard (STL) container in which we'll push back the read value. + */ + virtual void operator()( const eoserial::Array& array, unsigned int i, Container & container ) const = 0; + }; + + /** + * @brief BaseAlgorithm for retrieving primitive variables. + * + * This one should be used to retrieve primitive (and types which implement operator>>) variables, for instance + * int, double, std::string, etc... + */ + template + struct UnpackAlgorithm : public BaseAlgorithm + { + void operator()( const eoserial::Array& array, unsigned int i, C & container ) const + { + typename C::value_type t; + unpack( array, i, t ); + container.push_back( t ); + } + }; + + /** + * @brief BaseAlgorithm for retrieving eoserial::Persistent objects. + * + * This one should be used to retrieve objects which implement eoserial::Persistent. + */ + template + struct UnpackObjectAlgorithm : public BaseAlgorithm + { + void operator()( const eoserial::Array& array, unsigned int i, C & container ) const + { + typename C::value_type t; + unpackObject( array, i, t ); + container.push_back( t ); + } + }; + + /** + * @brief General algorithm for array deserialization. + * + * Applies the BaseAlgorithm to each contained variable in the eoserial::Array. + */ + template class UnpackAlgorithm> + inline void deserialize( Container & array ) + { + UnpackAlgorithm< Container > algo; + for( unsigned int i = 0, size = this->size(); + i < size; + ++i) + { + algo( *this, i, array ); + } + } }; - /** - * @brief BaseAlgorithm for retrieving primitive variables. - * - * This one should be used to retrieve primitive (and types which implement operator>>) variables, for instance - * int, double, std::string, etc... - */ - template - struct UnpackAlgorithm : public BaseAlgorithm - { - void operator()( const eoserial::Array& array, unsigned int i, C & container ) const - { - typename C::value_type t; - unpack( array, i, t ); - container.push_back( t ); - } - }; - - /** - * @brief BaseAlgorithm for retrieving eoserial::Persistent objects. - * - * This one should be used to retrieve objects which implement eoserial::Persistent. - */ - template - struct UnpackObjectAlgorithm : public BaseAlgorithm - { - void operator()( const eoserial::Array& array, unsigned int i, C & container ) const - { - typename C::value_type t; - unpackObject( array, i, t ); - container.push_back( t ); - } - }; - - /** - * @brief General algorithm for array deserialization. - * - * Applies the BaseAlgorithm to each contained variable in the eoserial::Array. - */ - template class UnpackAlgorithm> - inline void deserialize( Container & array ) - { - UnpackAlgorithm< Container > algo; - for( unsigned int i = 0, size = this->size(); - i < size; - ++i) - { - algo( *this, i, array ); - } - } -}; - } // namespace eoserial # endif // __EOSERIAL_ARRAY_H__ diff --git a/eo/src/serial/Entity.h b/eo/src/serial/Entity.h index df10002d..6fec3485 100644 --- a/eo/src/serial/Entity.h +++ b/eo/src/serial/Entity.h @@ -1,9 +1,42 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_ENTITY_H__ # define __EOSERIAL_ENTITY_H__ -# include -# include +# include // ostream +/** + * @brief Contains all the necessary entities to serialize eo objects into JSON objects. + * + * Allows serialization from user objects into JSON objects, if they implement the interface + * eoserial::Serializable or eoserial::Persistent. The following user objects can be serialized: + * - primitive types (int, std::string, ...), in particular every type that can be written into a + * std::stringstream. + * - objects which implement eoserial::Serializable. + * - array of serializable things (primitive or serializable objects). + * + * @ingroup Utilities + * @defgroup Serialization Serialization helpers + */ namespace eoserial { @@ -12,6 +45,8 @@ namespace eoserial * * This class represents a JSON entity, which can be JSON objects, * strings or arrays. It is the base class for the JSON hierarchy. + * + * @ingroup Serialization */ class Entity { diff --git a/eo/src/serial/Object.cpp b/eo/src/serial/Object.cpp index 3e557a12..dd859052 100644 --- a/eo/src/serial/Object.cpp +++ b/eo/src/serial/Object.cpp @@ -1,40 +1,60 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # include "Object.h" using namespace eoserial; namespace eoserial { - -std::ostream& Object::print( std::ostream& out ) const -{ - out << '{'; - bool first = true; - for(JsonValues::const_iterator it = begin(), end = this->end(); - it != end; - ++it) + std::ostream& Object::print( std::ostream& out ) const { - if ( first ) + out << '{'; + bool first = true; + for(JsonValues::const_iterator it = begin(), end = this->end(); + it != end; + ++it) { - first = false; - } else { - out << ", "; - } + if ( first ) + { + first = false; + } else { + out << ", "; + } - out << '"' << it->first << "\":"; // key - it->second->print( out ); // value + out << '"' << it->first << "\":"; // key + it->second->print( out ); // value + } + out << "}\n"; + return out; + } + + Object::~Object() + { + for(JsonValues::iterator it = begin(), end = this->end(); + it != end; + ++it) + { + delete it->second; } - out << "}\n"; - return out; -} - -Object::~Object() -{ - for(JsonValues::iterator it = begin(), end = this->end(); - it != end; - ++it) - { - delete it->second; } -} } // namespace eoserial diff --git a/eo/src/serial/Object.h b/eo/src/serial/Object.h index 36769252..20fbdbf7 100644 --- a/eo/src/serial/Object.h +++ b/eo/src/serial/Object.h @@ -1,66 +1,87 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_OBJECT_H__ # define __EOSERIAL_OBJECT_H__ # include # include -# include # include "Entity.h" # include "Serializable.h" namespace eoserial { - -/** - * @brief JSON Object - * - * This class represents a JSON object, which is basically a dictionnary - * of keys (strings) and values (JSON entities). - */ -class Object : public eoserial::Entity, public std::map< std::string, eoserial::Entity* > -{ -public: - typedef std::map JsonValues; - /** - * @brief Adds a pair into the JSON object. - * @param key The key associated with the eoserial object - * @param eoserial The JSON object as created with framework. + * @brief JSON Object + * + * This class represents a JSON object, which is basically a dictionnary + * of keys (strings) and values (JSON entities). + * + * @ingroup Serialization */ - void add( const std::string& key, eoserial::Entity* json ) + class Object : public eoserial::Entity, public std::map< std::string, eoserial::Entity* > { - (*this)[ key ] = json; - } + public: + typedef std::map JsonValues; - /** - * @brief Adds a pair into the JSON object. - * @param key The key associated with the eoserial object - * @param obj A JSON-serializable object - */ - void add( const std::string& key, const eoserial::Printable* obj ) - { - (*this)[ key ] = obj->pack(); - } + /** + * @brief Adds a pair into the JSON object. + * @param key The key associated with the eoserial object + * @param eoserial The JSON object as created with framework. + */ + void add( const std::string& key, eoserial::Entity* json ) + { + (*this)[ key ] = json; + } - /** - * @brief Deserializes a Serializable class instance from this JSON object. - * @param obj The object we want to rebuild. - */ - void deserialize( eoserial::Persistent & obj ) - { - obj.unpack( this ); - } + /** + * @brief Adds a pair into the JSON object. + * @param key The key associated with the eoserial object + * @param obj A JSON-serializable object + */ + void add( const std::string& key, const eoserial::Printable* obj ) + { + (*this)[ key ] = obj->pack(); + } - /** - * @brief Dtor - */ - ~Object(); + /** + * @brief Deserializes a Serializable class instance from this JSON object. + * @param obj The object we want to rebuild. + */ + void deserialize( eoserial::Persistent & obj ) + { + obj.unpack( this ); + } - /** - * @brief Prints the content of a JSON object into a stream. - */ - virtual std::ostream& print( std::ostream& out ) const; -}; + /** + * @brief Dtor + */ + ~Object(); + + /** + * @brief Prints the content of a JSON object into a stream. + */ + virtual std::ostream& print( std::ostream& out ) const; + }; } // namespace eoserial # endif // __EOSERIAL_OBJECT_H__ diff --git a/eo/src/serial/Parser.cpp b/eo/src/serial/Parser.cpp index c7822d29..258174c8 100644 --- a/eo/src/serial/Parser.cpp +++ b/eo/src/serial/Parser.cpp @@ -1,7 +1,25 @@ -# include +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # include -# include -# include # include "Parser.h" diff --git a/eo/src/serial/Parser.h b/eo/src/serial/Parser.h index f0a94ee2..5bcdc597 100644 --- a/eo/src/serial/Parser.h +++ b/eo/src/serial/Parser.h @@ -1,3 +1,24 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_PARSER_H__ # define __EOSERIAL_PARSER_H__ @@ -6,6 +27,8 @@ # include "Object.h" /** + * @file Parser.h + * * This file contains a tiny JSON parser used in DAE. This parser just handles * a subset of JSON grammar, with the following restrictions : * - all strings must be surrounded by double quotes. @@ -26,6 +49,8 @@ namespace eoserial * This parser does just retrieve values and does NOT check the structure of * the input. This implies that if the input is not correct, the result is undefined * and can result to a failure on execution. + * + * @ingroup Serialization */ class Parser { diff --git a/eo/src/serial/Serializable.h b/eo/src/serial/Serializable.h index 482a918a..715e9c97 100644 --- a/eo/src/serial/Serializable.h +++ b/eo/src/serial/Serializable.h @@ -1,43 +1,65 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_SERIALIZABLE_H__ # define __EOSERIAL_SERIALIZABLE_H__ -# include - namespace eoserial { + class Object; // to avoid recursive inclusion with JsonObject -class Object; // to avoid recursive inclusion with JsonObject - -/** - * @brief Interface showing that object can be written to a eoserial type - * (currently JSON). - */ -class Printable -{ -public: /** - * @brief Serializes the object to JSON format. - * @return A JSON object created with new. + * @brief Interface showing that object can be written to a eoserial type + * (currently JSON). + * + * @ingroup Serialization */ - virtual eoserial::Object* pack() const = 0; -}; + class Printable + { + public: + /** + * @brief Serializes the object to JSON format. + * @return A JSON object created with new. + */ + virtual eoserial::Object* pack() const = 0; + }; -/** - * @brief Interface showing that object can be eoserialized (written and read - * from an input). - * - * Note : Persistent objects should have a default non-arguments constructor. - */ -class Persistent : public Printable -{ - public: /** - * @brief Loads class fields from a JSON object. - * @param json A JSON object. Programmer doesn't have to delete it, it - * is automatically done. + * @brief Interface showing that object can be eoserialized (written and read + * from an input). + * + * Note : Persistent objects should have a default non-arguments constructor. + * + * @ingroup Serialization */ - virtual void unpack(const eoserial::Object* json) = 0; -}; + class Persistent : public Printable + { + public: + /** + * @brief Loads class fields from a JSON object. + * @param json A JSON object. Programmer doesn't have to delete it, it + * is automatically done. + */ + virtual void unpack(const eoserial::Object* json) = 0; + }; } // namespace eoserial diff --git a/eo/src/serial/String.cpp b/eo/src/serial/String.cpp index deba05a0..c5088278 100644 --- a/eo/src/serial/String.cpp +++ b/eo/src/serial/String.cpp @@ -1,3 +1,24 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # include "String.h" namespace eoserial diff --git a/eo/src/serial/String.h b/eo/src/serial/String.h index 6d81937f..526cab36 100644 --- a/eo/src/serial/String.h +++ b/eo/src/serial/String.h @@ -1,3 +1,24 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_STRING_H__ # define __EOSERIAL_STRING_H__ @@ -9,72 +30,73 @@ namespace eoserial { + /** + * @brief JSON String + * + * Wrapper for string, so as to be used as a JSON object. + * + * @ingroup Serialization + */ + class String : public eoserial::Entity, public std::string + { + public: -/** - * @brief JSON String - * - * Wrapper for string, so as to be used as a JSON object. - */ -class String : public eoserial::Entity, public std::string -{ - public: + /** + * @brief Default ctor. + * @param str The string we want to wrap. + */ + String( const std::string& str ) : std::string( str ) {} - /** - * @brief Default ctor. - * @param str The string we want to wrap. - */ - String( const std::string& str ) : std::string( str ) {} + /** + * @brief Ctor used only when parsing. + */ + String( ) {} - /** - * @brief Ctor used only on parsing. - */ - String( ) {} + /** + * @brief Prints out the string. + */ + virtual std::ostream& print( std::ostream& out ) const; - /** - * @brief Prints out the string. - */ - virtual std::ostream& print( std::ostream& out ) const; + /** + * @brief Deserializes the current String into a given primitive type value. + * @param value The value in which we're writing. + */ + template + inline void deserialize( T & value ); - /** - * @brief Deserializes the current String into a given primitive type value. - * @param value The value in which we're writing. - */ - template - inline void deserialize( T & value ); + protected: + // Copy and reaffectation are forbidden + explicit String( const String& _ ); + String& operator=( const String& _ ); + }; - protected: - // Copy and reaffectation are forbidden - explicit String( const String& _ ); - String& operator=( const String& _ ); -}; + /** + * @brief Casts a eoserial::String into a primitive value, or in a type which at + * least overload operator>>. + * + * @param value A reference to the variable we're writing into. + * + * It's not necessary to specify the variable type, which can be infered by compiler when + * invoking. + */ + template + inline void String::deserialize( T & value ) + { + std::stringstream ss; + ss.precision(std::numeric_limits::digits10 + 1); + ss << *this; + ss >> value; + } -/** - * @brief Casts a eoserial::String into a primitive value, or in a type which at - * least overload operator>>. - * - * @param value A reference to the variable we're writing into. - * - * It's not necessary to specify the variable type, which can be infered by compiler when - * invoking. - */ -template -inline void String::deserialize( T & value ) -{ - std::stringstream ss; - ss.precision(std::numeric_limits::digits10 + 1); - ss << *this; - ss >> value; -} - -/** - * @brief Specialization for strings, which don't need to be converted through - * a stringstream. - */ -template<> -inline void String::deserialize( std::string & value ) -{ - value = *this; -} + /** + * @brief Specialization for strings, which don't need to be converted through + * a stringstream. + */ + template<> + inline void String::deserialize( std::string & value ) + { + value = *this; + } } // namespace eoserial diff --git a/eo/src/serial/Utils.h b/eo/src/serial/Utils.h index f40c08d9..33172a74 100644 --- a/eo/src/serial/Utils.h +++ b/eo/src/serial/Utils.h @@ -1,3 +1,24 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_UTILS_H__ # define __EOSERIAL_UTILS_H__ @@ -7,7 +28,7 @@ namespace eoserial { - /***************************** + /* *************************** * DESERIALIZATION FUNCTIONS * ***************************** These functions are useful for casting eoserial::objects into simple, primitive @@ -54,7 +75,7 @@ namespace eoserial static_cast( array[ index ] )->deserialize< Container, UnpackAlgorithm >( container ); } - /******************************* + /* ***************************** *** SERIALIZATION FUNCTIONS *** ******************************* These functions are useful for casting classic objects and diff --git a/eo/src/serial/eoSerial.h b/eo/src/serial/eoSerial.h index a10f6c01..55a116f0 100644 --- a/eo/src/serial/eoSerial.h +++ b/eo/src/serial/eoSerial.h @@ -1,3 +1,24 @@ +/* +(c) Thales group, 2012 + + 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: + Benjamin Bouvier +*/ # ifndef __EOSERIAL_HEADERS__ # define __EOSERIAL_HEADERS__ diff --git a/eo/src/utils/eoParallel.cpp b/eo/src/utils/eoParallel.cpp index 41865198..fc57910c 100644 --- a/eo/src/utils/eoParallel.cpp +++ b/eo/src/utils/eoParallel.cpp @@ -21,7 +21,7 @@ Contact: http://eodev.sourceforge.net Authors: -Caner Candan + Caner Candan */ @@ -37,7 +37,7 @@ eoParallel::eoParallel() : _nthreads( 0, "parallelize-nthreads", "Define the number of threads you want to use, nthreads = 0 means you want to use all threads available", '\0' ), _enableResults( false, "parallelize-enable-results", "Enable the generation of results", '\0' ), _doMeasure( false, "parallelize-do-measure", "Do some measures during execution", '\0' ), - _packetSize( 1U, "parallelize-packet-size", "Number of elements which should be sent at a time during a parallel evaluation based on message passing.", '\0'), + _packetSize( 1U, "parallelize-packet-size", "Number of elements which should be sent in a single message during a parallel evaluation based on message passing.", '\0'), _t_start(0) { } diff --git a/eo/src/utils/eoParallel.h b/eo/src/utils/eoParallel.h index 3aae8e43..b812fecc 100644 --- a/eo/src/utils/eoParallel.h +++ b/eo/src/utils/eoParallel.h @@ -20,8 +20,7 @@ Contact: http://eodev.sourceforge.net Authors: -Caner Candan - + Caner Candan */ /** @defgroup Parallel Parallel diff --git a/eo/src/utils/eoTimer.h b/eo/src/utils/eoTimer.h index 8aa09c51..edecce62 100644 --- a/eo/src/utils/eoTimer.h +++ b/eo/src/utils/eoTimer.h @@ -1,38 +1,84 @@ -# ifndef __TIMER_H__ -# define __TIMER_H__ +/* +(c) Thales group, 2012 -# include -# include + 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. -# include -# include + 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. -# include "utils/eoParallel.h" + 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: + Benjamin Bouvier +*/ +# ifndef __EO_TIMER_H__ +# define __EO_TIMER_H__ + +# include // time() +# include // rusage() + +# include // std::vector +# include // std::map + +# include "utils/eoParallel.h" // eo::parallel # ifdef WITH_MPI +// For serialization purposes # include # include # include # endif -// TODO TODOB commenter +/** + * @brief Timer allowing to measure time between a start point and a stop point. + * + * This timer allows the user to measure user time, system time and wallclock time + * between two points. Basically, user time is time spent in developer code ; system + * time is time spent during the IO wait and system calls ; wallclock is the difference + * of time we could observe by measuring time with a watch. + * + * @ingroup Utilities + */ class eoTimer { public: + /** + * @brief Default ctor. Begins all the timers. + */ eoTimer() - { - restart(); - } - - void restart() { uuremainder = 0; usremainder = 0; + restart(); + } + + /** + * @brief Restarts all the timers and launch the measure. + */ + void restart() + { wc_start = time(NULL); getrusage( RUSAGE_SELF, &_start ); } + /** + * @brief Measures the user time spent since the last restart(). + * + * If the number of elapsed seconds is zero, the spent milliseconds are + * added to a remainder. If the remainder exceeds one second, it is + * added to the number of elapsed seconds. + * + * @return Number of seconds elapsed in user space. + */ long int usertime() { struct rusage _now; @@ -44,12 +90,21 @@ class eoTimer if( uuremainder > 1000000) { ++result; - uuremainder = 0; + uuremainder -= 1000000; } } return result; } + /** + * @brief Measures the system time spent since the last restart(). + * + * If the number of elapsed seconds is zero, the spent milliseconds are + * added to a remainder. If the remainder exceeds one second, it is + * added to the number of elapsed seconds. + * + * @return Number of seconds elapsed in system (kernel) space. + */ long int systime() { struct rusage _now; @@ -61,28 +116,90 @@ class eoTimer if( usremainder > 1000000) { ++result; - usremainder = 0; + usremainder -= 1000000; } } return result; } + /** + * @brief Measures the wallclock time spent since the last restart(). + * + * @return Number of seconds elapsed, as a double. + */ double wallclock() { return std::difftime( std::time(NULL) , wc_start ); } protected: + // Structure used to measure user and system time. struct rusage _start; + // Remainder (in milliseconds) for user time. long int uuremainder; + // Remainder (in milliseconds) for system time. long int usremainder; + // Structure used to measure wallclock time. time_t wc_start; }; +/** + * @brief Registers a group of statistics, each statistic corresponding to user, system and wallclock times distribution. + * + * This class helps the user to measure time in different parts of an application. A name is associated to a statistic, + * on each call to start() and stop() for this name, a new number is added to the statistic, for each of the three + * measured times. + * + * The statistics are only registered if the option "--parallelized-do-measure" is set to true, which can be checked + * thanks to global object eo::parallel. + * + * This shows how the eoTimerStat can be used : + * @code + * eoTimerStat timerStat; + * timerStat.start("first_point"); + * for( int i = 0; i < 1000; ++i ) + * { + * timerStat.start("single_computation"); + * single_computation( i ); + * timerStat.stop("single_computation"); + * } + * // After this loop, timerStat contains a statistic of key "single_computation" which contains 1000 measures for + * // each type of time. + * timerStat.stop("first_point"); + * // After this line, timerStat contains another statistic of key "first_point" which counted the duration of the + * // whole loop. + * + * int singleComputationUsertimeMean = 0; + * for( int i = 0; i < 1000; ++i ) + * { + * singleComputationUsertimeMean += timerStat.stats()["single_computation"].utime[i]; + * } + * std::cout << "Mean of user time spent in single computation: " << singleComputationUsertimeMean / 1000. << std::endl; + * @endcode + * + * When using MPI, these statistics can be readily be serialized, so as to be sent over a network, for instance. + * + * Implementation details: this eoTimerStat is in fact a map of strings (key) / Stat (value). Stat is an internal + * structure directly defined in the class, which contains three vectors modeling the distributions of the different + * types of elapsed times. Another map of strings (key) / eoTimer (value) allows to effectively retrieve the different + * times. The struct Stat will be exposed to client, which will use its members ; however, + * the client doesn't have anything to do directly with the timer, that's why the two maps are splitted. + * + * @ingroup Utilities + */ class eoTimerStat { public: + /** + * @brief Statistic related to a key (name). + * + * This structure is the value in the map saved in the eoTimerStat. It contains the statistic bound to a key, + * which are the user time distribution, the system time distribution and the wallclock time distribution, as + * std::vector s. + * + * It can readily be serialized with boost when compiling with mpi. + */ struct Stat { std::vector utime; @@ -93,25 +210,27 @@ class eoTimerStat friend class boost::serialization::access; /** - * Serializes the statistique in a boost archive (useful for boost::mpi) + * Serializes the single statistic in a boost archive (useful for boost::mpi). + * Just serializes the 3 vectors. */ template - void serialize( Archive & ar, const unsigned int version ) - { - ar & utime & stime & wtime; - (void) version; // avoid compilation warning - } + void serialize( Archive & ar, const unsigned int version ) + { + ar & utime & stime & wtime; + (void) version; // avoid compilation warning + } # endif }; #ifdef WITH_MPI - // Gives access to boost serialization - friend class boost::serialization::access; + // Gives access to boost serialization + friend class boost::serialization::access; - /** - * Serializes the map of statistics in a boost archive (useful for boost::mpi) - */ - template + /** + * Serializes the timerStat object in a boost archive (useful for boost::mpi). + * Just serializes the map. + */ + template void serialize( Archive & ar, const unsigned int version ) { ar & _stats; @@ -119,6 +238,14 @@ class eoTimerStat } # endif + /** + * @brief Starts a new measure for the given key. + * + * This is only performed if parallel.doMeasure() is true, which is equivalent to the fact that + * parser found "--parallel-do-measure=1" in command line args. + * + * @param key The key of the statistic. + */ void start( const std::string & key ) { if( eo::parallel.doMeasure() ) @@ -127,6 +254,16 @@ class eoTimerStat } } + /** + * @brief Stops the mesure for the given key and saves the elapsed times. + * + * Must follow a call of start with the same key. + * + * This is only performed if parallel.doMeasure() is true, which is equivalent to the fact that + * parser found "--parallel-do-measure=1" in command line args. + * + * @param key The key of the statistic. + */ void stop( const std::string& key ) { if( eo::parallel.doMeasure() ) @@ -139,13 +276,18 @@ class eoTimerStat } } - std::map< std::string, Stat > stats() + /** + * @brief Getter for the statistics map. + */ + std::map< std::string, Stat >& stats() { return _stats; } protected: + // Statistics map: links a key (string) to a statistic. std::map< std::string, Stat > _stats; + // Timers map: links a key to its timer. std::map< std::string, eoTimer > _timers; };