So let's say that I have created a main-worker program with the following steps:
1 - main sends tasks to all workers
2 - faster workers accomplish tasks and send the results back to the main
3 - main receives the results from the fastest workers and sends new tasks to everyone
4 - faster workers are ready to receive the task, but slower workers have to interrupt or cancel the old, slow, task that they were doing, in order to start the new task at the same time as the faster worker
I know how to do all the steps, except for step 4, where I would have to interrupt what the slower workers are doing in order to proceed to the next task.
Here is an example of an incomplete code that is missing that part:
#include <mpi.h>
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
int main(int argc, char* argv[])
{
MPI_Init(&argc,&argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
if (rank == 0) {
int value = 17;
string valuec = "Hello";
for(int i = 1; i < world_size; i++){
int result = MPI_Send(valuec.c_str(), valuec.length(), MPI_CHAR, i, 0, MPI_COMM_WORLD);
if (result == MPI_SUCCESS)
std::cout << "Rank 0 OK!" << std::endl;
}
int workersDone = 0;
MPI_Status status;
int flag = 0;
while(1){
flag=0;
MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status);
if(flag==1){
workersDone++;
cout << "Workers done: " << workersDone << endl;
}
if(workersDone >= world_size/2){/* here the main moves on
before all workers are done
*/
cout << "Main breaking" << endl;
break;
}
}
/* interruption Here:
How do I make the main tell to the slow workers
interrupt or cancel what they were doing in order
to receive new tasks
*/
// New tasks should go here here
} else if (rank != 0) {
int receivedMessages = 0;
while(1){
MPI_Status status;
int flag = 0;
MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &status);
if(flag==1){
receivedMessages++;
int value;
char buffer[256];
int result = MPI_Recv(&buffer, 256, MPI_CHAR, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
cout << rank << " received " << buffer << endl;
sleep(rank); /* this hypothetical task will be slower
in some workers, faster in others. In the
final version of code of course this
will not be a sleep command, and the time
it takes will not be proportional to the
process rank.
*/
MPI_Send(buffer, sizeof(buffer), MPI_CHAR, 0, 0, MPI_COMM_WORLD);
cout << rank << " breaking" << endl;
break;
}
}
}
MPI_Finalize();
return 0;
}