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(); }