Gather
MPI_Gather
MPI_Gather este o funcție care reprezintă inversul lui MPI_Scatter, în sensul că un proces primește elemente de la fiecare proces din comunicator, inclusiv de la el însuși, și le unifică într-o singură colecție.
Semnătura funcției este următoarea: int MPI_Gather(void* send_data, int send_count, MPI_Datatype send_datatype, void* recv_data, int recv_count, MPI_Datatype recv_datatype, int root, MPI_Comm communicator), unde:
- send_data (↓) - reprezintă datele care trimise de fiecare proces către procesul cu id-ul root
- send_count (↓) - reprezintă dimensiunea bucății trimisă de fiecare proces (de regulă se pune ca fiind dimensiunea_totală / număr_de_procese).
- send_datatype (↓) - tipul datelor trimise de către procese
- recv_data (↑) - reprezintă datele care sunt primite și stocate de către procesul root
- recv_count (↓) - dimensiunea datelor primite (de regulă dimensiunea_totală / număr_de_procese)
- recv_datatype (↓) - tipul datelor primite de către procesul root (de regulă este același cu send_datatype)
- root (↓) - identificatorul procesului care primește datele (inclusiv de la el însuși)
- communicator (↓) - comunicatorul din care fac parte procesele (de regulă MPI_COMM_WORLD)
O ilustrare a modului cum funcționează MPI_Gather:
Mai jos aveți un exemplu de MPI_Scatter folosit împreună cu MPI_Gather:
Exemplu
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define ROOT 0
#define CHUNK_SIZE 5 // numarul de elemente per proces
int main (int argc, char **argv) {
int rank, proc, a;
int* arr;
int* process_arr;
int* result_arr;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &proc);
if (rank == ROOT) {
arr = malloc (CHUNK_SIZE * proc * sizeof(int));
for (int i = 0; i < proc * CHUNK_SIZE; ++i) {
arr[i] = 0;
}
}
process_arr = malloc (CHUNK_SIZE * sizeof(int));
MPI_Scatter(arr, CHUNK_SIZE, MPI_INT, process_arr, CHUNK_SIZE, MPI_INT, ROOT, MPI_COMM_WORLD);
for (int i = 0; i < CHUNK_SIZE; i++) {
printf("Before: rank [%d] - value = %d\n", rank, process_arr[i]);
process_arr[i] = i;
printf("After: rank [%d] - value = %d\n", rank, process_arr[i]);
}
if (rank == ROOT) {
result_arr = malloc (CHUNK_SIZE * proc * sizeof(int));
}
MPI_Gather(process_arr, CHUNK_SIZE, MPI_INT, result_arr, CHUNK_SIZE, MPI_INT, ROOT, MPI_COMM_WORLD);
if (rank == ROOT) {
for (int i = 0; i < CHUNK_SIZE * proc; i++) {
printf("%d ", result_arr[i]);
}
printf("\n");
}
if (rank == ROOT) {
free(arr);
free(result_arr);
}
free(process_arr);
MPI_Finalize();
return 0;
}