Example #1
0
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;
}