0

For example, I have a root process which sends some computations to be completed by worker processes. But because I have limited (4) processes I have to share the workload to all of them so I send multiple times. The workaround that I have found is this:


    int me = MPI.COMM_WORLD.Rank();

    if(me == 0) {
        sendToWorkers(); //Sends more than once to workers.
    }
    else {
        while(true) {//wait indefinitely, accept data received from root process and work on it.
            MPI.COMM_WORLD.Recv(Buf, 0, Buf.length, MPI.INT, 0, 0);
            doTask(Buf);
        }
    }

Now the problem arises that I want to send data that has completed processing back to the root process but I can't do another while(true);. I am sure there must be a much more elegant way to accomplish this.

EDIT 1: The reason why I want to send to root process is because it is cleaner. However, alternatively I can just print computed solutions from the worker processes but the output is all mangled up due to interleaving. Declaring the print method to be synchronized doesn't work.

Meta Xenology
  • 142
  • 2
  • 9

1 Answers1

0

One simple solution is at the end of task distribution, master must sent a "FINISH/STOP/END" (any custom message to indicate that tasks are over) message to all workers. Workers getting the finish message exits the loop and sends the result back to the master. Master can start a loop with total tasks and waits for those results.

From your example shown, this is a typical master worker model use-case. Here when you send a task to a worker using MPI_Send(), there is a corresponding MPI_Recv() in your worker process. After receiving task, you perform doTask(Buf). Then you again goes to the loop. So in your case, to summarise, you receive a new task only after computing the previously received task for that rank right? In that case, master process can also wait for reply from any of the finished tasks and can send new tasks based on that. May be you can consider that approach. If your doTask uses thread, then this becomes complicated. Each worker nodes then haves to keep track of its tasks and after all the tasks are completed, master should start a loop and waits for the results.

Or you can use multithreaded implementation. You may use separate thread for send and receive in master.

j23
  • 3,139
  • 1
  • 6
  • 13
  • I don't wait. I do something like ```for(int i = 0; i < n; i++) {m = i % number_of_processors; if(m!= 0) {MPI.COMM_WORLD.Send(Buf, 0, Buf.length, MPI.INT, m, 0);}``` As in I send multiple requests for a function to be executed multiple times from each process. That's why I guess I have the ```while(true)``` I have to busy wait until all tasks have been received. – Meta Xenology Mar 13 '20 at 16:25
  • Alternative way would be to not send the data back but print the solution from the workers but in that case my output to ```stdout``` is all mangled up because of interleaving and using ```synchronized``` doesn't work. – Meta Xenology Mar 13 '20 at 16:38
  • after receiving the data, you are also computing the task right. Loop across Recv - DoTask - Recv right? – j23 Mar 13 '20 at 17:11
  • Yes, I do Recv and then run a method. Each process runs the method more than once with different arguments. – Meta Xenology Mar 13 '20 at 17:40