struct MPI_Data_t{ int numOfCpu; int columnGrid; int rowGrid; //this is calculated int rank; int subRank; int nodeSize, nodeRank; int flag; int sharedMemSize; int winDisp; int *sharedMemModel; float *pMem, *pMemLocal; int color; MPI_Win sharedMemoryWin; MPI_Aint winSize; MPI_Comm allComm, nodeComm; MPI_Comm rowComm; }; float collector_toy(vector& xVec) //this function will be called from the root process { MPI_Request request; MPI_Status status; float retVal = 0; float noData = 0; //send xvector to all of the workers and they will start to call the f(x) MPI_Ibcast(&xVec[0], PROB_SIZE, MPI_FLOAT, Cluster::rootProcessId, subComm, &request); MPI_Wait (&request, &status); //wait for the end of non-blocking broadcast MPI_Barrier(subComm); //wait for syncronization of the threads int mpiState; mpiState = MPI_Gather(&noData, 1, MPI_FLOAT, resultArr1, 1, MPI_FLOAT, Cluster::rootProcessId, subComm); //collect data from all node mpiState = MPI_Gather(&noData, 1, MPI_FLOAT, resultArr2, 1, MPI_FLOAT, Cluster::rootProcessId, subComm); //collect data from all node //now we gathered all float result data we shall compute the sum of them float a = 0; float b = 0; for(int i = 0; i < numOfWorkers; i++) { a += resultArr1[i+1]; b += resultArr2[i+1]; } retVal = (a / b); retVal = -retVal; return retVal; } float toyDummy[2]; float* ToyObjFun(float* x, int cpuId, int numOfWorkers )//the cpuId can be used to define different behavior { int start_process = (541 - 1) / numOfWorkers * (cpuId - 1); //cpuId > 0 int end_process = start_process + ((541 - 1) / numOfWorkers); int idxOffset = (cpuId - 1) * PROB_SIZE/numOfWorkers; toyDummy[0] = 0; toyDummy[1] = 0; for (int j = start_process; j < end_process; j++) { for(int i=0;i<100000000;i++) { toyDummy[0] += x[j+idxOffset]*i; } toyDummy[0] /= PROB_SIZE/numOfWorkers; toyDummy[1] = toyDummy[0]*j; } return toyDummy; } void App_toy_function(MPI_Data_t& mMpiData) { std::chrono::_V2::system_clock::time_point searchStartTime; std::chrono::duration searchElapsedTime; int loopNum = 1; double searchTimer; float yRes; int numOfCpu = mMpiData.numOfCpu; int rank = mMpiData.rank; subComm = mMpiData.allComm; if(rank == 0){ cout << "Master node starting" << endl; MPI_Barrier(mMpiData.allComm); //wait for syncronization of the threads vector x(PROB_SIZE, 0.5); while(loopNum) { searchStartTime = std::chrono::high_resolution_clock::now(); yRes = collector_toy(x); searchElapsedTime = std::chrono::high_resolution_clock::now() - searchStartTime; searchTimer = searchElapsedTime.count(); cout << yRes << ", " << searchTimer << " s" << endl; loopNum--; } } else { float timer; float* ptrResult; float f32Result[2]; bool isAppOK = true; float x[PROB_SIZE]; int flag; MPI_Request request; MPI_Status status; MPI_Barrier(mMpiData.allComm); //wait for syncronization of the threads while(1) { MPI_Ibcast(x, PROB_SIZE, MPI_FLOAT, Cluster::rootProcessId, mMpiData.allComm, &request); while(1) //run timout until data is received { MPI_Test(&request, &flag, &status); if(timer > MPI_APP_TIMEOUT) { isAppOK = false; break; //break out from the inner while } if(flag) { break; } } if(isAppOK) { ptrResult = ToyObjFun(x, rank, (numOfCpu - 1)); f32Result[0] = ptrResult[0]; f32Result[1] = ptrResult[1]; MPI_Barrier(mMpiData.allComm); //wait for syncronization of the processes MPI_Gather(&f32Result[0], 1, MPI_FLOAT, resultArr1, 1, MPI_FLOAT,Cluster::rootProcessId, mMpiData.allComm); MPI_Gather(&f32Result[1], 1, MPI_FLOAT, resultArr2, 1, MPI_FLOAT,Cluster::rootProcessId, mMpiData.allComm); } else // master node is not responding -> app hang -> quit { std::cout << "App finished on CPU: " << rank << std::endl; break; } } } } int main() { int subRootNodeNum; float dummy; float* rxPtr; MPI_Data_t mMpiData; memset(&mMpiData, 0, sizeof(MPI_Data_t)); /* MPI initialization */ mMpiData.columnGrid = 10; mMpiData.allComm = MPI_COMM_WORLD; MPI_Init(NULL, NULL); MPI_Comm_rank(mMpiData.allComm, &mMpiData.rank); LOG_D(mMpiData.rank, "MPI initialization done"); MPI_Comm_size(mMpiData.allComm, &mMpiData.numOfCpu); //get how much CPU are present for calculation LOG_D(mMpiData.rank, "ranking done"); LOG_D(mMpiData.rank,"Allocation of ram started"); numOfWorkers = mMpiData.numOfCpu - 1; resultArr1 = (float *) malloc(sizeof(float) * mMpiData.numOfCpu); //allocate memory for storing of the result data resultArr2 = (float *) malloc(sizeof(float) * mMpiData.numOfCpu); //allocate memory for storing of the result data LOG_D(mMpiData.rank,"Allocation of ram done"); if(mMpiData.rank == 0) { cout << "Num of cpu " << mMpiData.numOfCpu << endl; cout << "Num of workers: " << numOfWorkers << endl; } LOG_D(mMpiData.rank,"Starting app"); App_toy_function(mMpiData); MPI_Barrier(mMpiData.allComm); //Blocks the caller until all processes in the communicator have called it; free(resultArr1); free(resultArr2); if(mMpiData.rank == 0) { std::cout << "----------------------------------------------" << std::endl; } return 0; }