peoMultiStart.h

00001 /*
00002 * <peoMultiStart.h>
00003 * Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2008
00004 * (C) OPAC Team, LIFL, 2002-2008
00005 *
00006 * Sebastien Cahon, Alexandru-Adrian Tantar, Clive Canape
00007 *
00008 * This software is governed by the CeCILL license under French law and
00009 * abiding by the rules of distribution of free software.  You can  use,
00010 * modify and/ or redistribute the software under the terms of the CeCILL
00011 * license as circulated by CEA, CNRS and INRIA at the following URL
00012 * "http://www.cecill.info".
00013 *
00014 * As a counterpart to the access to the source code and  rights to copy,
00015 * modify and redistribute granted by the license, users are provided only
00016 * with a limited warranty  and the software's author,  the holder of the
00017 * economic rights,  and the successive licensors  have only  limited liability.
00018 *
00019 * In this respect, the user's attention is drawn to the risks associated
00020 * with loading,  using,  modifying and/or developing or reproducing the
00021 * software by the user in light of its specific status of free software,
00022 * that may mean  that it is complicated to manipulate,  and  that  also
00023 * therefore means  that it is reserved for developers  and  experienced
00024 * professionals having in-depth computer knowledge. Users are therefore
00025 * encouraged to load and test the software's suitability as regards their
00026 * requirements in conditions enabling the security of their systems and/or
00027 * data to be ensured and,  more generally, to use and operate it in the
00028 * same conditions as regards security.
00029 * The fact that you are presently reading this means that you have had
00030 * knowledge of the CeCILL license and that you accept its terms.
00031 *
00032 * ParadisEO WebSite : http://paradiseo.gforge.inria.fr
00033 * Contact: paradiseo-help@lists.gforge.inria.fr
00034 *
00035 */
00036 #ifndef __peoMultiStart_h
00037 #define __peoMultiStart_h
00038 
00039 #include <vector>
00040 
00041 #include "core/service.h"
00042 #include "core/messaging.h"
00043 
00049 template < typename EntityType > class peoMultiStart : public Service
00050   {
00051 
00052   public:
00053 
00056     template < typename AlgorithmType > peoMultiStart( AlgorithmType& externalAlgorithm )
00057     {
00058       singularAlgorithm = new Algorithm< AlgorithmType >( externalAlgorithm );
00059       algorithms.push_back( singularAlgorithm );
00060       aggregationFunction = new NoAggregationFunction();
00061     }
00062 
00065     template < typename AlgorithmReturnType, typename AlgorithmDataType > peoMultiStart( AlgorithmReturnType (*externalAlgorithm)( AlgorithmDataType& ) )
00066     {
00067       singularAlgorithm = new FunctionAlgorithm< AlgorithmReturnType, AlgorithmDataType >( externalAlgorithm );
00068       algorithms.push_back( singularAlgorithm );
00069       aggregationFunction = new NoAggregationFunction();
00070     }
00071 
00075     template < typename AlgorithmType, typename AggregationFunctionType > peoMultiStart( std::vector< AlgorithmType* >& externalAlgorithms, AggregationFunctionType& externalAggregationFunction )
00076     {
00077       for ( unsigned int index = 0; index < externalAlgorithms.size(); index++ )
00078         {
00079           algorithms.push_back( new Algorithm< AlgorithmType >( *externalAlgorithms[ index ] ) );
00080         }
00081       aggregationFunction = new AggregationAlgorithm< AggregationFunctionType >( externalAggregationFunction );
00082     }
00083 
00087     template < typename AlgorithmReturnType, typename AlgorithmDataType, typename AggregationFunctionType > peoMultiStart( std::vector< AlgorithmReturnType (*)( AlgorithmDataType& ) >& externalAlgorithms, AggregationFunctionType& externalAggregationFunction )
00088     {
00089       for ( unsigned int index = 0; index < externalAlgorithms.size(); index++ )
00090         {
00091           algorithms.push_back( new FunctionAlgorithm< AlgorithmReturnType, AlgorithmDataType >( externalAlgorithms[ index ] ) );
00092         }
00093       aggregationFunction = new AggregationAlgorithm< AggregationFunctionType >( externalAggregationFunction );
00094     }
00095 
00097     ~peoMultiStart()
00098     {
00099       for ( unsigned int index = 0; index < data.size(); index++ ) delete data[ index ];
00100       for ( unsigned int index = 0; index < algorithms.size(); index++ ) delete algorithms[ index ];
00101       delete aggregationFunction;
00102     }
00103 
00106     template < typename Type > void operator()( Type& externalData )
00107     {
00108       for ( typename Type::iterator externalDataIterator = externalData.begin(); externalDataIterator != externalData.end(); externalDataIterator++ )
00109         {
00110           data.push_back( new DataType< EntityType >( *externalDataIterator ) );
00111         }
00112       functionIndex = dataIndex = idx = num_term = 0;
00113       requestResourceRequest( data.size() * algorithms.size() );
00114       stop();
00115     }
00116 
00120     template < typename Type > void operator()( const Type& externalDataBegin, const Type& externalDataEnd )
00121     {
00122       for ( Type externalDataIterator = externalDataBegin; externalDataIterator != externalDataEnd; externalDataIterator++ )
00123         {
00124           data.push_back( new DataType< EntityType >( *externalDataIterator ) );
00125         }
00126       functionIndex = dataIndex = idx = num_term = 0;
00127       requestResourceRequest( data.size() * algorithms.size() );
00128       stop();
00129     }
00130 
00132     void packData();
00134     void unpackData();
00136     void execute();
00138     void packResult();
00140     void unpackResult();
00142     void notifySendingData();
00144     void notifySendingAllResourceRequests();
00145 
00146   private:
00147 
00157     template < typename Type > struct DataType;
00158     struct AbstractDataType
00159       {
00160         virtual ~AbstractDataType()
00161         { }
00162         template < typename Type > operator Type& ()
00163         {
00164           return ( dynamic_cast< DataType< Type >& >( *this ) ).data;
00165         }
00166       };
00167 
00168   template < typename Type > struct DataType : public AbstractDataType
00169       {
00170         DataType( Type& externalData ) : data( externalData )
00171         { }
00172         Type& data;
00173       };
00174 
00175     struct AbstractAlgorithm
00176       {
00177         virtual ~AbstractAlgorithm()
00178         { }
00179         virtual void operator()( AbstractDataType& dataTypeInstance )
00180         {}
00181       };
00182 
00183   template < typename AlgorithmType > struct Algorithm : public AbstractAlgorithm
00184       {
00185         Algorithm( AlgorithmType& externalAlgorithm ) : algorithm( externalAlgorithm )
00186         { }
00187         void operator()( AbstractDataType& dataTypeInstance )
00188         {
00189           algorithm( dataTypeInstance );
00190         }
00191         AlgorithmType& algorithm;
00192       };
00193 
00194   template < typename AlgorithmReturnType, typename AlgorithmDataType > struct FunctionAlgorithm : public AbstractAlgorithm
00195       {
00196         FunctionAlgorithm( AlgorithmReturnType (*externalAlgorithm)( AlgorithmDataType& ) ) : algorithm( externalAlgorithm )
00197         { }
00198         void operator()( AbstractDataType& dataTypeInstance )
00199         {
00200           algorithm( dataTypeInstance );
00201         }
00202         AlgorithmReturnType (*algorithm)( AlgorithmDataType& );
00203       };
00204 
00205     struct AbstractAggregationAlgorithm
00206       {
00207         virtual ~AbstractAggregationAlgorithm()
00208         { }
00209         virtual void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB )
00210         {}
00211       };
00212 
00213   template < typename AggregationAlgorithmType > struct AggregationAlgorithm : public AbstractAggregationAlgorithm
00214       {
00215         AggregationAlgorithm( AggregationAlgorithmType& externalAggregationAlgorithm ) : aggregationAlgorithm( externalAggregationAlgorithm )
00216         { }
00217         void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB )
00218         {
00219           aggregationAlgorithm( dataTypeInstanceA, dataTypeInstanceB );
00220         }
00221         AggregationAlgorithmType& aggregationAlgorithm;
00222       };
00223 
00224   struct NoAggregationFunction : public AbstractAggregationAlgorithm
00225       {
00226         void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB )
00227         {
00228 
00229           static_cast< EntityType& >( dataTypeInstanceA ) = static_cast< EntityType& >( dataTypeInstanceB );
00230         }
00231       };
00232 
00233     AbstractAlgorithm* singularAlgorithm;
00234     std::vector< AbstractAlgorithm* > algorithms;
00235     AbstractAggregationAlgorithm* aggregationFunction;
00236     EntityType entityTypeInstance;
00237     std::vector< AbstractDataType* > data;
00238     unsigned idx;
00239     unsigned num_term;
00240     unsigned dataIndex;
00241     unsigned functionIndex;
00242   };
00243 
00244 
00245 template < typename EntityType > void peoMultiStart< EntityType >::packData()
00246 {
00247 
00248   pack( functionIndex );
00249   pack( idx );
00250   pack( ( EntityType& ) *data[ idx++ ]  );
00251 
00252   // done with functionIndex for the entire data set - moving to another
00253   //  function/algorithm starting all over with the entire data set ( idx is set to 0 )
00254   if ( idx == data.size() )
00255     {
00256 
00257       ++functionIndex;
00258       idx = 0;
00259     }
00260 }
00261 
00262 template < typename EntityType > void peoMultiStart< EntityType >::unpackData()
00263 {
00264 
00265   unpack( functionIndex );
00266   unpack( dataIndex );
00267   unpack( entityTypeInstance );
00268 }
00269 
00270 template < typename EntityType > void peoMultiStart< EntityType >::execute()
00271 {
00272 
00273   // wrapping the unpacked data - the definition of an abstract algorithm imposes
00274   // that its internal function operator acts only on abstract data types
00275   AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance );
00276   algorithms[ functionIndex ]->operator()( *entityWrapper );
00277 
00278   delete entityWrapper;
00279 }
00280 
00281 template < typename EntityType > void peoMultiStart< EntityType >::packResult()
00282 {
00283 
00284   pack( dataIndex );
00285   pack( entityTypeInstance );
00286 }
00287 
00288 template < typename EntityType > void peoMultiStart< EntityType >::unpackResult()
00289 {
00290 
00291   unpack( dataIndex );
00292   unpack( entityTypeInstance );
00293 
00294   // wrapping the unpacked data - the definition of an abstract algorithm imposes
00295   // that its internal function operator acts only on abstract data types
00296   AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance );
00297   aggregationFunction->operator()( *data[ dataIndex ], *entityWrapper );
00298   delete entityWrapper;
00299 
00300   num_term++;
00301 
00302   if ( num_term == data.size() * algorithms.size() )
00303     {
00304 
00305       getOwner()->setActive();
00306       resume();
00307     }
00308 }
00309 
00310 template < typename EntityType > void peoMultiStart< EntityType >::notifySendingData()
00311 {}
00312 
00313 template < typename EntityType > void peoMultiStart< EntityType >::notifySendingAllResourceRequests()
00314 {
00315 
00316   getOwner()->setPassive();
00317 }
00318 
00319 
00320 #endif

Generated on Thu Mar 13 15:55:03 2008 for ParadisEO-PEO-ParallelanddistributedEvolvingObjects by  doxygen 1.4.7