Id init( int argc, char** argv, bool& doUnitTests, bool& doRegressionTests, unsigned int& benchmark ) { unsigned int numCores = getNumCores(); int numNodes = 1; int myNode = 0; bool isInfinite = 0; int opt; benchmark = 0; // Default, means don't do any benchmarks. Cinfo::rebuildOpIndex(); #ifdef USE_MPI /* // OpenMPI does not use argc or argv. // unsigned int temp_argc = 1; int provided; MPI_Init_thread( &argc, &argv, MPI_THREAD_SERIALIZED, &provided ); */ MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &numNodes ); MPI_Comm_rank( MPI_COMM_WORLD, &myNode ); /* if ( provided < MPI_THREAD_SERIALIZED && myNode == 0 ) { cout << "Warning: This MPI implementation does not like multithreading: " << provided << "\n"; } */ // myNode = MPI::COMM_WORLD.Get_rank(); #endif /** * Here we allow the user to override the automatic identification * of processor configuration */ while ( ( opt = getopt( argc, argv, "hiqurn:b:B:" ) ) != -1 ) { switch ( opt ) { case 'i' : // infinite loop, used for multinode debugging, to give gdb something to attach to. isInfinite = 1; break; case 'n': // Multiple nodes numNodes = (unsigned int)atoi( optarg ); break; case 'b': // Benchmark: benchmark = atoi( optarg ); break; case 'B': // Benchmark plus dump data: handle later. break; case 'u': // Do unit tests, pass back. doUnitTests = 1; break; case 'r': // Do regression tests: pass back doRegressionTests = 1; break; case 'q': // quit immediately after completion. quitFlag = 1; break; case 'h': // help default: cout << "Usage: moose -help -infiniteLoop -unit_tests -regression_tests -quit -n numNodes -benchmark [ksolve intFire hhNet msg_<msgType>_<size>]\n"; exit( 1 ); } } if ( myNode == 0 ) { #if 0 cout << "on node " << myNode << ", numNodes = " << numNodes << ", numCores = " << numCores << endl; #endif } Id shellId; Element* shelle = new GlobalDataElement( shellId, Shell::initCinfo(), "root", 1 ); Id clockId = Id::nextId(); assert( clockId.value() == 1 ); Id classMasterId = Id::nextId(); Id postMasterId = Id::nextId(); Shell* s = reinterpret_cast< Shell* >( shellId.eref().data() ); s->setShellElement( shelle ); s->setHardware( numCores, numNodes, myNode ); s->loadBalance(); /// Sets up the Elements that represent each class of Msg. unsigned int numMsg = Msg::initMsgManagers(); new GlobalDataElement( clockId, Clock::initCinfo(), "clock", 1 ); new GlobalDataElement( classMasterId, Neutral::initCinfo(), "classes", 1); new GlobalDataElement( postMasterId, PostMaster::initCinfo(), "postmaster", 1 ); assert ( shellId == Id() ); assert( clockId == Id( 1 ) ); assert( classMasterId == Id( 2 ) ); assert( postMasterId == Id( 3 ) ); // s->connectMasterMsg(); Shell::adopt( shellId, clockId, numMsg++ ); Shell::adopt( shellId, classMasterId, numMsg++ ); Shell::adopt( shellId, postMasterId, numMsg++ ); assert( numMsg == 10 ); // Must be the same on all nodes. Cinfo::makeCinfoElements( classMasterId ); // This will be initialized within the Process loop, and better there // as it flags attempts to call the Reduce operations before ProcessLoop // Qinfo::clearReduceQ( numCores ); // Initialize the ReduceQ entry. // SetGet::setShell(); // Msg* m = new OneToOneMsg( shelle, shelle ); // assert ( m != 0 ); while ( isInfinite ) // busy loop for debugging under gdb and MPI. ; return shellId; }