0
votes

I am new to MPI, so sorry if this sounds stupid. I want a process to have an MPI_Irecv. If it has been called for a task, then it finds a result and sends the result back to the process that called it. How can I check if it has been actually assigned to a task? So that I can have an if{} in which that task takes place while the rest of the process continues with other stuff.

Code example:

for (i=0;i<size_of_Q;i++) {
    MPI_Irecv( &shmeio, 1, mpi_point_C, root, 77, MPI_COMM_WORLD, &req );
    //I want to put an if right here.
    //If it's true process does task.
    //Finds a number. then
    MPI_Isend( &Bestcandidate, 1, mpi_point_C, root, 66, MPI_COMM_WORLD, &req );
    //so that it can return the result.
    //if it wasn't assigned a task it carries on with its other tasks. 
} //(here is where for loop  ends)
1
What is a task for you? How does it find out it has been assigned it? Why you need non-blocking? Where are your MPI_Wait()s?Vladimir F Героям слава
how does it find out it has been assigned it is actually my question. I'm new to MPI so i don't know how i should use the MPI_Wait()Dimitris Gabr

1 Answers

1
votes

You might be confusing what MPI is supposed to do. MPI isn't really a tasking-based model as compared to some others (map reduce, some parts of OpenMP, etc.). MPI has historically focused on SPMD (single program multiple data) types of applications. That's not to say that MPI can't handle MPMD (there's an entire chapter in the standard about dynamic processes and most launchers can run different executables on different ranks.

With that in mind, when you start your job, you'll usually have all of the processes that you'll ever have (unless you're using dynamic processing like MPI_COMM_SPAWN). You probably used something like:

mpiexec -n 8 ./my_program arg1 arg2 arg3

Many times, if people are trying to emulate a tasking (or master/worker) model, they'll treat rank 0 as the special "master":

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (0 == rank) {
    while (/* work not done */) {
        /* Check if parts of work are done */
        /* Send work to ranks without work */
    }
} else {
    while (/* work not done */ {
        /* Get work from master */
        /* Compute */
        /* Send results to master */
    }
}

Often, when waiting for the work, you'll do something like:

for (i = 1; i < num_process; i++) {
    MPI_Irecv(&result[i], ..., &requests[i]);
}

This will set up the receives for each rank that will send you work. Then later, you can do something like:

MPI_Testany(num_processes - 1, requests, &index, &flag, statuses);
if (flag) {
     /* Process work */
     MPI_Send(work_data, ..., index, ...);
}

This will check to see if any of the requests (the handles used to track the status of a nonblocking operation) are completed and will then send new work to the worker that finished.

Obviously, all of this code is not copy/paste ready. You'll have to figure out how/if it applies to your work and adapt it accordingly.