Infection Functions

find_infected

For each process, this function determines its infected x locations and infected y locations

image

We have already set the states of the infected people and the positions of all the people, but we need to specifically set the positions of the infected people and store them in the our_infected_x_locations and our_infected_y_locations arrays. We do this by marching through the our_states array and checking whether the state at each cell is INFECTED. If it is, we add the locations of the current infected person from the our_x_locations and our_y_locations arrays to the our_infected_x_locations and our_infected_y_locations arrays. We determine the ID of the current infected person using the our_current_infected_person variable:

    for(our_person1 = 0; our_person1 <= our->our_number_of_people - 1; our_person1++)
    {
        if(our->our_states[our_person1] == INFECTED)
        {
            our->our_infected_x_locations[our_current_infected_person] = 
            our->our_x_locations[our_person1];
            our->our_infected_y_locations[our_current_infected_person] =
            our->our_y_locations[our_person1];
            our_current_infected_person++;
        }
    }

share_infected

First, for each process, this function sends its count of infected people to all the other processes and receives their counts

image
    // Each process sends its count of infected people to all the
    // other processes and receives their counts
    MPI_Allgather(&our->our_num_infected, 1, MPI_INT, recvcounts, 1, 
        MPI_INT, MPI_COMM_WORLD);

This step is handled by the MPI command MPI_Allgather whose arguments are as follows:

  • &our_num_infected – the address of the sending buffer (the thing being sent).
  • 1 – the count of things being sent.
  • MPI_INT – the datatype of things being sent.
  • recvcounts – the receive buffer (an array of things being received).
  • 1 – the count of things being received.
  • MPI_INT – the datatype of things being received.
  • MPI_COMM_WORLD – the communicator of processes that send and receive data.

Once the data has been sent and received, we count the total number of infected people by adding up the values in the recvcounts array and storing the result in the total_num_infected variable:

    global->total_num_infected = 0;
    int current_rank;
    for(current_rank = 0; current_rank <= total_number_of_processes - 1;
        current_rank++)
    {
        global->total_num_infected += recvcounts[current_rank];
    }

Next, for each process, the function sends the x locations of its infected people to all the other processes and receives the x locations of their infected people

For this send and receive, we need to use MPI_Allgatherv instead of MPI_Allgather. This is because each process has a varying number of infected people, so it needs to be able to send a variable number of x locations. To do this, we first need to set up the displacements in the receive buffer; that is, we need to indicate how many elements each process will send and at what points in the receive array they will appear. We can do this with a displs array, which will contain a list of the displacements in the receive buffer:

    // Each process sends the x locations of its infected people to 
    // all the other processes and receives the x locations of their 
    // infected people
    MPI_Allgatherv(our->our_infected_x_locations, our->our_num_infected, MPI_INT, 
        global->their_infected_x_locations, recvcounts, displs, 
        MPI_INT, MPI_COMM_WORLD);

We are now ready to call the MPI_Allgatherv. Here are its arguments:

  • our_infected_x_locations – the send buffer (array of things to send).
  • our_num_infected – the count of elements in the send buffer.
  • MPI_INT – the datatype of the elements in the send buffer.
  • their_infected_x_locations – the receive buffer (array of things to receive).
  • recvcounts – an array of counts of elements in the receive buffer
  • displs – the list of displacements in the receive buffer, as determined above.
  • MPI_INT – the data type of the elements in the receive buffer.
  • MPI_COMM_WORLD – the communicator of processes that send and receive data.

Once the command is complete, each process will have the full array of the x locations of the infected people from each process, stored in the their_infected_x_locations array.

Finally, each process sends the y locations of its infected people to all the other processes and receives the y locations of their infected people

    // Each process sends the y locations of its infected people 
    // to all the other processes and receives the y locations of their 
    // infected people
    MPI_Allgatherv(our->our_infected_y_locations, our->our_num_infected, MPI_INT, 
        global->their_infected_y_locations, recvcounts, displs, 
        MPI_INT, MPI_COMM_WORLD);

The y locations are sent and received just as the x locations are sent and received. In fact, the function calls have exactly 2 letters difference; the x’s in the Allgatherv from last step. are replaced by y’s in the Allgatherv in this step.

Note that the code will only execute previous two steps if MPI is enabled. If it is not enabled, the code simply copies the our_infected_x_locations and our_infected_y_locations arrays into the their_infected_x_locations and their_infected_y_locations arrays and the our_num_infected variable into the total_num_infected variable.