/******************************************************************* * * DESCRIPTION: class ParallelProcessorAdmin * * AUTHOR: Alejandro Troccoli * * * EMAIL: mailto://atroccol@dc.uba.ar * * DATE: 04/10/2000 *******************************************************************/ /** include files **/ #include "pprocadm.h" // header #include "model.h" // class Model #include "atomic.h" #include "flatcoup.h" #include "coupled.h" #include "psimulat.h" // class Simulator #include "pcoordin.h" // class Coordinator #ifndef NEWCOORDIN #include "pmcoordin.h" // class ParallelMCoordinator #include "pscoordin.h" // class ParallelSCoordinator #else #include "pmcoordin2.h" #include "pscoordin2.h" #endif #include "strutil.h" // lowerCase #include "proot.h" // class Root #include "pncoord.h" // class ParallelNodeCoordinator #include "pfcoord.h" // class ParallelFlatCoordinator /** public data **/ const ProcId ParallelProcessorAdmin::rootId( 0 ) ; const ProcId ParallelProcessorAdmin::ncBaseId( 10000 ) ; /** private data **/ ParallelProcessorAdmin *SingleParallelProcessorAdmin::instance( NULL ) ; /** public functions **/ /******************************************************************* * Function Name: ProcessorAdmin ********************************************************************/ ParallelProcessorAdmin::ParallelProcessorAdmin() { procIdCount = ParallelProcessorAdmin::rootId + 1; } /******************************************************************* * Function Name: ~ProcessorAdmin() * Description: destroys all the alive processors ********************************************************************/ ParallelProcessorAdmin::~ParallelProcessorAdmin() { for ( ProcessorDB::iterator cursor = procDB.begin(); cursor != procDB.end(); cursor++ ) delete cursor->second; } /******************************************************************* * Function Name: generateProcessor ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::generateProcessor( Atomic *atomic, const ProcId id ) { //#ifdef JACKY_DEBUG // ostream& jacky_os = JackyDebugStream::Instance().Stream(); // jacky_os << ">>generateProcessor(Atomic*) for model: " << atomic->asString() << " procId = " << id << endl << flush; //#endif ParallelSimulator *sim = new ParallelSimulator( atomic ); atomic->processor( (ParallelProcessor *)sim); add2DB( sim, id ); return *sim; } /******************************************************************* * Function Name: generateProcessor ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::generateProcessor( Coupled *coupled, const ProcId id ) { //#ifdef JACKY_DEBUG // ostream& jacky_os = JackyDebugStream::Instance().Stream(); // jacky_os << ">>generateProcessor(Coupled*) for model: " << coupled->asString() << " procId = " << id << endl << flush; //#endif ParallelCoordinator *coord; #ifndef NEWCOORDIN //Coordinator can be either master or slave. if (coupled->isLocalMaster()) coord = new ParallelMCoordinator( coupled ); else coord = new ParallelSCoordinator( coupled ); #else //Coordinator can be either master or slave. if (coupled->isLocalMaster()) coord = new ParallelMCoordinator2( coupled ); else coord = new ParallelSCoordinator2( coupled ); #endif #if defined(JACKY_INFREQ_STATEMANAGER) && defined(INFREQSTATEMANAGER) //[2006-03-20] ----------------------------- #if defined(JACKY_FOSSIL_COLLECTION_STRATEGY_A) //[2006-03-26] //Jacky: add a flag to identify ParallelCoordinators (ParallelMCoordinator & ParallelSCoordinator) //this is used in GVTManager when InfreqStateManager is employed //Do not include these coordinators in the calculation of lVT of the LAST states coord->skipCalculateLVT = true; #endif //endJACKY_FOSSIL_COLLECTION_STRATEGY_A [2006-03-26] #endif //end JACKY_INFREQ_STATEMANAGER && INFREQSTATEMANAGER //[2006-03-20] -------------------------------------- coupled->processor( (ParallelProcessor *)coord ); add2DB( coord, id ); return *coord; } /******************************************************************* * Function Name: generateProcessor ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::generateProcessor( CoupledCell *coupled, const ProcId id ) { //#ifdef JACKY_DEBUG // ostream& jacky_os = JackyDebugStream::Instance().Stream(); // jacky_os << ">>generateProcessor(CoupledCell*) for model: " << coupled->asString() << " procId = " << id << endl << flush; //#endif return generateProcessor( (Coupled*) coupled, id ); } /******************************************************************* * Function Name: generateProcessor ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::generateProcessor( FlatCoupledCell *coupled, const ProcId id ) { //#ifdef JACKY_DEBUG // ostream& jacky_os = JackyDebugStream::Instance().Stream(); // jacky_os << ">>???? generateProcessor(FlatCoupledCell*) for model: " << coupled->asString() // << " procId = " << id << endl << flush; //#endif ParallelCoordinator *coord;// = new ParallelCoordinator( coupled ) ; coupled->processor( (ParallelProcessor*) coord ); add2DB( coord, id ) ; return *coord ; } /******************************************************************* * Function Name: generateRoot ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::generateRoot( RootModel * rootmdl, const ProcId pid) { //#ifdef JACKY_DEBUG // ostream& jacky_os = JackyDebugStream::Instance().Stream(); // jacky_os << ">>generateRoot(RootModel*) for model: " << rootmdl->asString() << " procId = " << pid << endl << flush; //#endif ParallelRoot *root = new ParallelRoot( rootmdl ) ; #if defined(JACKY_INFREQ_STATEMANAGER) && defined(INFREQSTATEMANAGER) //[2006-03-20] ----------------------------- #if defined(JACKY_FOSSIL_COLLECTION_STRATEGY_A) //[2006-03-26] //set the value of flag "skipCalculateLVT" based on whether the TOP model has output ports or not //if TOP model has no output ports [ParallelMainSimulator::isTopHasOutputPorts() returns false], then we //need to set flag skipCalculateLVT = true if(ParallelMainSimulator::Instance().isTopHasOutputPorts() == false){ root->skipCalculateLVT = true; } //otherwise, the Root will participate in the calculation, its skipCalculateLVT is false by defualt! #endif //end JACKY_FOSSIL_COLLECTION_STRATEGY_A [2006-03-26] #endif //end JACKY_INFREQ_STATEMANAGER && INFREQSTATEMANAGER //[2006-03-20] -------------------------------------- rootmdl->processor( (ParallelProcessor*) root ); add2DB( root, pid ) ; return *root ; } /******************************************************************* * Function Name: generateNodeCoordinator ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::generateNodeCoordinator( NodeCoordinatorModel * ncmdl, const ProcId pid) { //#ifdef JACKY_DEBUG // ostream& jacky_os = JackyDebugStream::Instance().Stream(); // jacky_os << ">>generateNC(NodeCoordinatorModel*) for model: " << ncmdl->asString() << " procId = " << pid // << endl << flush; //#endif ParallelNodeCoordinator *nc = new ParallelNodeCoordinator( ncmdl ) ; #ifdef JACKY_UNIQUE_LOG //[2006-04-26] ================================= //when the local NC is created, we set the localNC accordingly //so that all other processors on that node can easily get the //outFileQ[logIndex] defined in it ParallelMainSimulator::Instance().localNC = nc; #ifdef JACKY_DEBUG ostream& jacky_os = JackyDebugStream::Instance().Stream(); jacky_os << "[ONE_LOG] set the localNC = " << nc << endl << flush; #endif #endif //end JACKY_UNIQUE_LOG [2006-04-26] ============================= ncmdl->processor( (ParallelProcessor*) nc ); add2DB( nc, pid ) ; return *nc ; } /******************************************************************* * Function Name: generateFlatCoordinator ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::generateFlatCoordinator( FlatCoordinatorModel * fcmdl, const ProcId pid) { //#ifdef JACKY_DEBUG // ostream& jacky_os = JackyDebugStream::Instance().Stream(); // jacky_os << ">>generateFC(FlatCoordinatorModel*) for model: " << fcmdl->asString() << " procId = " << pid << endl << flush; //#endif ParallelFlatCoordinator *fc = new ParallelFlatCoordinator( fcmdl ) ; fcmdl->processor( (ParallelProcessor*) fc ); add2DB( fc, pid ) ; return *fc ; } /******************************************************************* * Function Name: processor ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::processor( const ProcId &id ) { ProcessorDB::iterator cursor( procDB.find( id ) ); if( cursor == procDB.end() ) { InvalidProcessorIdException e; e.addText( string( "The processor id " ) + id + " is invalid!" ) ; MTHROW( e ) ; } MASSERT( cursor->second ); return *( cursor->second ); } /******************************************************************* * Function Name: processor ********************************************************************/ ParallelProcessor &ParallelProcessorAdmin::processor( const string &name ) { string lower( lowerCase( name ) ) ; ProcessorDB::iterator cursor( procDB.begin() ); while( cursor != procDB.end() && cursor->second->description() != lower ) cursor ++ ; if( cursor == procDB.end() ) { InvalidProcessorIdException e ; e.addText( string( "The processor " ) + lowerCase( name ) + " is invalid!" ); MTHROW( e ) ; } return *( cursor->second ); } /******************************************************************* * Function Name: add2DB ********************************************************************/ ParallelProcessorAdmin &ParallelProcessorAdmin::add2DB( ParallelProcessor *newProc, const ProcId &newId ) { newProc->id( newId ); procDB[ newId ] = newProc; return *this; } /******************************************************************* * Function Name: model ********************************************************************/ void ParallelProcessorAdmin::model( const ProcId & pid, Model * model ) { procModelDB[pid] = model; } /******************************************************************* * Function Name: model ********************************************************************/ Model &ParallelProcessorAdmin::model( const ProcId & pid) { ProcessorModelDB::iterator cursor( procModelDB.find( pid ) ); if( cursor == procModelDB.end() ) { InvalidProcessorIdException e; e.addText( string( "The processor id " ) + pid + " is invalid!" ) ; MTHROW( e ) ; } MASSERT( cursor->second ); return *( cursor->second ); } /******************************************************************* * Function Name: showProcessors ********************************************************************/ void ParallelProcessorAdmin::showProcessors( ostream &out = cout) { ProcessorDB::iterator cursor( procDB.begin() ); out << "Current processors: " << endl; while( cursor != procDB.end()) { ParallelProcessor *proc = cursor->second; out << "Processor Id: " << proc->id() << "\tDescription: " << proc->description() << endl; out << "\tModel Id: " << (proc->model()).id() << " " << proc->model().asString() << endl; out << "\tParent Id: " << proc->model().parentId()<< endl; cursor ++; } } #ifdef JACKY_REVISION /************************************************************************************************************************ * Function Name: findProcId() * Description: search a specified ProcId in the ProcessorDB, if found, it returns true; otherwise, it returns false. * This is useful when we want to identify whether a received message was sent from a local or remote source. * [see Message::asStringReceived() for more information] **************************************************************************************************************************/ bool ParallelProcessorAdmin::findProcId(const ProcId & pid){ //if the "pid" does not exist as a KEY in the map, find() will return procDB.end() return procDB.find(pid) != procDB.end(); } #endif #ifdef JACKY_DEBUG /******************************************************************* * Function Name: getProcessorDB() * retieve the ProcessorDB for debugging purpose ********************************************************************/ ParallelProcessorAdmin::ProcessorDB &ParallelProcessorAdmin::getProcessorDB(){ return procDB; } #endif