/* * * Copyright (C) DOLPHIN Project-Team, INRIA Futurs, 2006-2008 * (C) OPAC Team, LIFL, 2002-2008 * * Sebastien Cahon, Alexandru-Adrian Tantar, Clive Canape * * This software is governed by the CeCILL license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL * license as circulated by CEA, CNRS and INRIA at the following URL * "http://www.cecill.info". * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited liability. * * In this respect, the user's attention is drawn to the risks associated * with loading, using, modifying and/or developing or reproducing the * software by the user in light of its specific status of free software, * that may mean that it is complicated to manipulate, and that also * therefore means that it is reserved for developers and experienced * professionals having in-depth computer knowledge. Users are therefore * encouraged to load and test the software's suitability as regards their * requirements in conditions enabling the security of their systems and/or * data to be ensured and, more generally, to use and operate it in the * same conditions as regards security. * The fact that you are presently reading this means that you have had * knowledge of the CeCILL license and that you accept its terms. * * ParadisEO WebSite : http://paradiseo.gforge.inria.fr * Contact: paradiseo-help@lists.gforge.inria.fr * */ #ifndef __peoMultiStart_h #define __peoMultiStart_h #include #include "core/service.h" #include "core/messaging.h" //! @class peoMultiStart //! @brief Class allowing the launch of several algorithms //! @see Service //! @version 1.1 //! @date january 2008 template < typename EntityType > class peoMultiStart : public Service { public: //! @brief Constructor //! @param AlgorithmType& externalAlgorithm template < typename AlgorithmType > peoMultiStart( AlgorithmType& externalAlgorithm ) { singularAlgorithm = new Algorithm< AlgorithmType >( externalAlgorithm ); algorithms.push_back( singularAlgorithm ); aggregationFunction = new NoAggregationFunction(); } //! @brief Constructor //! @param AlgorithmReturnType (*externalAlgorithm)( AlgorithmDataType& ) template < typename AlgorithmReturnType, typename AlgorithmDataType > peoMultiStart( AlgorithmReturnType (*externalAlgorithm)( AlgorithmDataType& ) ) { singularAlgorithm = new FunctionAlgorithm< AlgorithmReturnType, AlgorithmDataType >( externalAlgorithm ); algorithms.push_back( singularAlgorithm ); aggregationFunction = new NoAggregationFunction(); } //! @brief Constructor //! @param std::vector< AlgorithmType* >& externalAlgorithms //! @param AggregationFunctionType& externalAggregationFunction template < typename AlgorithmType, typename AggregationFunctionType > peoMultiStart( std::vector< AlgorithmType* >& externalAlgorithms, AggregationFunctionType& externalAggregationFunction ) { for ( unsigned int index = 0; index < externalAlgorithms.size(); index++ ) { algorithms.push_back( new Algorithm< AlgorithmType >( *externalAlgorithms[ index ] ) ); } aggregationFunction = new AggregationAlgorithm< AggregationFunctionType >( externalAggregationFunction ); } //! @brief Constructor //! @param std::vector< AlgorithmReturnType (*)( AlgorithmDataType& ) >& externalAlgorithms //! @param AggregationFunctionType& externalAggregationFunction template < typename AlgorithmReturnType, typename AlgorithmDataType, typename AggregationFunctionType > peoMultiStart( std::vector< AlgorithmReturnType (*)( AlgorithmDataType& ) >& externalAlgorithms, AggregationFunctionType& externalAggregationFunction ) { for ( unsigned int index = 0; index < externalAlgorithms.size(); index++ ) { algorithms.push_back( new FunctionAlgorithm< AlgorithmReturnType, AlgorithmDataType >( externalAlgorithms[ index ] ) ); } aggregationFunction = new AggregationAlgorithm< AggregationFunctionType >( externalAggregationFunction ); } //! @brief Destructor ~peoMultiStart() { for ( unsigned int index = 0; index < data.size(); index++ ) delete data[ index ]; for ( unsigned int index = 0; index < algorithms.size(); index++ ) delete algorithms[ index ]; delete aggregationFunction; } //! @brief operator on the template type //! @param Type& externalData template < typename Type > void operator()( Type& externalData ) { for ( typename Type::iterator externalDataIterator = externalData.begin(); externalDataIterator != externalData.end(); externalDataIterator++ ) { data.push_back( new DataType< EntityType >( *externalDataIterator ) ); } functionIndex = dataIndex = idx = num_term = 0; requestResourceRequest( data.size() * algorithms.size() ); stop(); } //! @brief operator on the template type //! @param Type& externalDataBegin //! @param Type& externalDataEnd template < typename Type > void operator()( const Type& externalDataBegin, const Type& externalDataEnd ) { for ( Type externalDataIterator = externalDataBegin; externalDataIterator != externalDataEnd; externalDataIterator++ ) { data.push_back( new DataType< EntityType >( *externalDataIterator ) ); } functionIndex = dataIndex = idx = num_term = 0; requestResourceRequest( data.size() * algorithms.size() ); stop(); } //! @brief Function realizing packages of data void packData(); //! @brief Function reconstituting packages of data void unpackData(); //! @brief Function which executes the algorithm void execute(); //! @brief Function realizing packages of the result void packResult(); //! @brief Function reconstituting packages of result void unpackResult(); //! @brief Function notifySendingData void notifySendingData(); //! @brief Function notifySendingAllResourceRequests void notifySendingAllResourceRequests(); private: //! @param AbstractAlgorithm* singularAlgorithm //! @param std::vector< AbstractAlgorithm* > algorithms //! @param AbstractAggregationAlgorithm* aggregationFunction //! @param EntityType entityTypeInstance //! @param std::vector< AbstractDataType* > data //! @param unsigned idx //! @param unsigned num_term //! @param unsigned dataIndex //! @param unsigned functionIndex template < typename Type > struct DataType; struct AbstractDataType { virtual ~AbstractDataType() { } template < typename Type > operator Type& () { return ( dynamic_cast< DataType< Type >& >( *this ) ).data; } }; template < typename Type > struct DataType : public AbstractDataType { DataType( Type& externalData ) : data( externalData ) { } Type& data; }; struct AbstractAlgorithm { virtual ~AbstractAlgorithm() { } virtual void operator()( AbstractDataType& dataTypeInstance ) {} }; template < typename AlgorithmType > struct Algorithm : public AbstractAlgorithm { Algorithm( AlgorithmType& externalAlgorithm ) : algorithm( externalAlgorithm ) { } void operator()( AbstractDataType& dataTypeInstance ) { algorithm( dataTypeInstance ); } AlgorithmType& algorithm; }; template < typename AlgorithmReturnType, typename AlgorithmDataType > struct FunctionAlgorithm : public AbstractAlgorithm { FunctionAlgorithm( AlgorithmReturnType (*externalAlgorithm)( AlgorithmDataType& ) ) : algorithm( externalAlgorithm ) { } void operator()( AbstractDataType& dataTypeInstance ) { algorithm( dataTypeInstance ); } AlgorithmReturnType (*algorithm)( AlgorithmDataType& ); }; struct AbstractAggregationAlgorithm { virtual ~AbstractAggregationAlgorithm() { } virtual void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) {} }; template < typename AggregationAlgorithmType > struct AggregationAlgorithm : public AbstractAggregationAlgorithm { AggregationAlgorithm( AggregationAlgorithmType& externalAggregationAlgorithm ) : aggregationAlgorithm( externalAggregationAlgorithm ) { } void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) { aggregationAlgorithm( dataTypeInstanceA, dataTypeInstanceB ); } AggregationAlgorithmType& aggregationAlgorithm; }; struct NoAggregationFunction : public AbstractAggregationAlgorithm { void operator()( AbstractDataType& dataTypeInstanceA, AbstractDataType& dataTypeInstanceB ) { static_cast< EntityType& >( dataTypeInstanceA ) = static_cast< EntityType& >( dataTypeInstanceB ); } }; AbstractAlgorithm* singularAlgorithm; std::vector< AbstractAlgorithm* > algorithms; AbstractAggregationAlgorithm* aggregationFunction; EntityType entityTypeInstance; std::vector< AbstractDataType* > data; unsigned idx; unsigned num_term; unsigned dataIndex; unsigned functionIndex; }; template < typename EntityType > void peoMultiStart< EntityType >::packData() { pack( functionIndex ); pack( idx ); pack( ( EntityType& ) *data[ idx++ ] ); // done with functionIndex for the entire data set - moving to another // function/algorithm starting all over with the entire data set ( idx is set to 0 ) if ( idx == data.size() ) { ++functionIndex; idx = 0; } } template < typename EntityType > void peoMultiStart< EntityType >::unpackData() { unpack( functionIndex ); unpack( dataIndex ); unpack( entityTypeInstance ); } template < typename EntityType > void peoMultiStart< EntityType >::execute() { // wrapping the unpacked data - the definition of an abstract algorithm imposes // that its internal function operator acts only on abstract data types AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance ); algorithms[ functionIndex ]->operator()( *entityWrapper ); delete entityWrapper; } template < typename EntityType > void peoMultiStart< EntityType >::packResult() { pack( dataIndex ); pack( entityTypeInstance ); } template < typename EntityType > void peoMultiStart< EntityType >::unpackResult() { unpack( dataIndex ); unpack( entityTypeInstance ); // wrapping the unpacked data - the definition of an abstract algorithm imposes // that its internal function operator acts only on abstract data types AbstractDataType* entityWrapper = new DataType< EntityType >( entityTypeInstance ); aggregationFunction->operator()( *data[ dataIndex ], *entityWrapper ); delete entityWrapper; num_term++; if ( num_term == data.size() * algorithms.size() ) { getOwner()->setActive(); resume(); } } template < typename EntityType > void peoMultiStart< EntityType >::notifySendingData() {} template < typename EntityType > void peoMultiStart< EntityType >::notifySendingAllResourceRequests() { getOwner()->setPassive(); } #endif