示例#1
0
文件: master.cpp 项目: zapu/descrack
int Master::run(int argc, char** argv)
{
    init();

    if(!openFile(argv[1]))
    {
        printf("Failed to open file %s\n", argv[1]);
        return -1;
    }

    broadcastParams();

    char opcode;
    MPI_Status status;

    int dict_status = 0;
    int finished_count = 0;

    /*
        Communication goes as follows:
        - Slave sends opcode (char) to master, one of the following:
            - 0x00 - Send me work!
            - 0x01 - Receive my chains! (full package)
            - 0x02 - Receive my chains! (not full pkg)
        - Master reacts, either recving more data or just responding.
            For 0x00, master can either reply '0x01' which is "No more work" or
            0x00 followed with iterator state.
     */
    while(finished_count < m_size - 1)
    {
        MPI_Recv(&opcode, 1, MPI_CHAR, MPI_ANY_SOURCE, COMM_ID_OPCODE, MPI_COMM_WORLD, &status);
        switch(opcode)
        {
            case 0x00:
                if(dict_status == 0)
                {
                    sendWork(status.MPI_SOURCE, &dict_status);
                }
                else
                {
                    static char noMoreWorkOp = 0x01;
                    MPI_Send(&noMoreWorkOp, 1, MPI_CHAR, status.MPI_SOURCE, COMM_ID_DATA, MPI_COMM_WORLD);
                    finished_count++;
                }
                break;
            case 0x01:
                recvChains(status.MPI_SOURCE);
                break;
            case 0x02:
                recvChains(status.MPI_SOURCE, true);
                break;
        }
    }

    fclose(m_table_file);
    return 0;
}
void Solver::firstDistribution() {
    // cout << "Prvni distribuce" << endl;

    //nasimuluju ze vsichni krome mastra chteji praci
    for (int i = 1; i < numberOfProcesses; ++i) {
        sendWork(i);
    }

    firstWorkDistribution = false;
}
int main(int argc, char* argv[]){

    // Initialize MPI
    // Find out my identity in the default communicator
    MPI_Init(&argc, &argv);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    //used to store the final results
    std::vector<result_t> finalResults;
    //init the k value
    int k = 0;

    if(argc > 1){
        try{
            k = atoi(argv[1]);
            if(k < 0){
                throw "just need to throw a random exception to catch`";
            }
        }
        catch(...){
            std::cerr<<"k must be a positive integer"<<std::endl;
            return 0;
        }

    }

    //init the custom openmpi datatype
    MPI_Datatype ResultMpiType;
    //wrapper function to set up the custom type
    createMPIResultStruct(&ResultMpiType);




    // Master
    if (rank == 0){
        // ++++++++++++++++++++++++++++++
        // Master process
        // ++++++++++++++++++++++++++++++

        // check the arugmumants
        if (argc < 2){
            std::cout << "Usage: " << argv[0] << " [k value] [directory path:default(/cluster)]" << std::endl;
            return 0;
        }

        std::string folderPath;

        //set the default for the folder to use
        if(argc == 2){
            folderPath = "/cluster";
        }
        else{
            folderPath = argv[2];
        }


        Directory dir;

        if(!dir.set_path(folderPath)){
            std::cerr<<"Directory either not found or not a directory"<<std::endl;
            return 0;
        }


        //test for a correct k value
        try{
            k = atoi(argv[1]);
            if(k < 0){
                throw "just need to throw a random exception to catch`";
            }
        }
        catch(...){
            std::cerr<<"k must be a positive integer"<<std::endl;
            return 0;
        }

        auto test = dir.get_files();
        searchVector_t searchVector;
        Timing wallClock;
        double timeResults[NUM_TIME_RESULTS];

        //initlize timing holder
        for(int i = 0; i < NUM_TIME_RESULTS; i++){
            timeResults[i] = 0;
        }

        wallClock.start();
        //get the first vector the first file in the the directory as the search vector
        if(!getFirstVector(test.at(0),&searchVector)){
            std::cerr << "Couldn't get the search vector" << std::endl;
            return 0;
        }
        std::cout << "Sending work to workers" << std::endl;
        sendWork(test,&ResultMpiType,k,&finalResults,searchVector.data,timeResults);



        //wait for the workers to finish to collect the results
        MPI_Barrier(MPI_COMM_WORLD);

        wallClock.end();
        std::cout<<"wallClock time: "<<wallClock.get_elapse()<<std::endl;

        //get com size for timming results
        int threadCount;
        MPI_Comm_size(MPI_COMM_WORLD, &threadCount);

        //creat a vector fromt the timing results
        std::vector<double> finalTimingVec;

        finalTimingVec.push_back(threadCount);
        finalTimingVec.push_back(k);
        finalTimingVec.push_back(wallClock.get_elapse());
        finalTimingVec.insert(finalTimingVec.end(),timeResults,timeResults+NUM_TIME_RESULTS);

        //output the timing vector to the timing for all the tests
        output_timing_vector_to_file("times.csv",finalTimingVec,1);

        //output the final results to a vector
        output_result_vector_to_file("results.csv", &finalResults);
    }
    else{
        // ++++++++++++++++++++++++++++++
        // Workers
        // ++++++++++++++++++++++++++++++

        doWork(&ResultMpiType,k);

        //used for the barrier in master
        MPI_Barrier(MPI_COMM_WORLD);
    }
    MPI_Type_free(&ResultMpiType);

    //Shut down MPI
    MPI_Finalize();

    return 1;

} // END of main
void Solver::processMessages() {
    int pesek; //sem si ulozim peska az mi prijde
    int foo; //sem ukladam vystup ze zpravy co neposila data
    int flag;
    char buffer[BUFFER_SIZE];
    MPI_Status status, status2;
    MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status);
    while (flag) {
        switch (status.MPI_TAG) {//tady staci rozsirit o ostatni messages a rozumim vsemu
            case MESSAGE_WORK_NONE:
            {
                MPI_Recv(&foo, 1, MPI_INT, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status2);
                requestWork = true; //nastavim ze budu zadat znovu
                //  cout << "proces: " << status.MPI_SOURCE << "mi NEposlal praci." << endl;
                ++failedWorkRequests;
                break;
            }

            case MESSAGE_WORK_DATA:
            {
                MPI_Recv(buffer, BUFFER_SIZE, MPI_PACKED, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status2);
                int position = 0;
                WorkMessage message;
                message.deserialize(buffer, position);
                //   cout << "jsem: " << myRank << " Obdrzel jsem: " << message << endl;
               // actualDepth = message.getItems()->front().getDepth(); //nastavim spravnou aktualni hloubku
                //    cout << "jsem: " << myRank << "nastavuji aktualni hloubku na: " << actualDepth << endl;
                for (int i = 0; i < message.getItems()->size(); ++i) {//tady to muze skripat
                    SpaceItem* spaceItem = new SpaceItem(*(message.getItems()->at(i).getBoard()), *(message.getItems()->at(i).getMoves()));
                    space.push_back(spaceItem);
                    actualDepth=spaceItem->getDepth();
                }
                requestWork = true;
                break;
            }
            case MESSAGE_WORK_REQUEST:
            {
                // workRequests->push_back(status.MPI_SOURCE); //ulozim si kdo chce praci
                MPI_Recv(&foo, 1, MPI_INT, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status2);
                sendWork(status.MPI_SOURCE);
                break;
            }


            case MESSAGE_TOKEN:
            {
                MPI_Recv(&pesek, 1, MPI_INT, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status2);
                //    cout << "Prisel Pesek od: " << status.MPI_SOURCE << " a mam: " << space.size() << " prace" << endl;
                tokenArrived = true;

                if (pesek != TOKEN_BLACK && pesek != TOKEN_WHITE) {
                    //     cout << "Nespravna hodnoa peska" << endl;
                    throw "vadny pesek!";
                }
                if (processColor == BLACK) {
                    tokenColor = TOKEN_BLACK;
                } else {
                    tokenColor = TOKEN_WHITE;
                }

                //osetreni pokud jsem master
                if (myRank == MASTER_RANK) {

                    if (pesek == TOKEN_WHITE) {
                        //  cout << "Jsem Master a dorazil mi WHITE pesek...koncim vypocet" << endl;
                        broadcast(MESSAGE_FINISHED);
                        MPI_Barrier(MPI_COMM_WORLD);
                        finished = true;

                        return;
                    } else {
                        tokenColor = TOKEN_WHITE;
                    }
                }
                break;
            }

            case MESSAGE_FINISHED:
            {
                MPI_Barrier(MPI_COMM_WORLD);
                finished = true;

                return;
            }
            default:
            {
                throw "Dorazila neplatna zprava!";
                break;
            }

        }
        MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status);
    }
    //sendWork();
}