Сумма массива с использованием MPI

Опубликовано: 4 Июля, 2021

Предварительное условие: MPI - Распределенные вычисления стали проще

Интерфейс передачи сообщений (MPI) - это библиотека процедур, которые можно использовать для создания параллельных программ на C или Fortran77. Он позволяет пользователям создавать параллельные приложения, создавая параллельные процессы и обмениваясь информацией между этими процессами.
MPI использует две основные процедуры связи:

  • MPI_Send , чтобы отправить сообщение другому процессу.
  • MPI_Recv , чтобы получить сообщение от другого процесса.

Синтаксис MPI_Send и MPI_Recv:

int MPI_Send (void * data_to_send, 
             int send_count, 
             MPI_Datatype send_type, 
             int destination_ID, 
             int тег, 
             MPI_Comm comm); 

int MPI_Recv (недействительно * полученные_данные, 
             int receive_count, 
             MPI_Datatype receive_type,
             int sender_ID, 
             int тег, 
             MPI_Comm comm, 
             MPI_Status * статус);

Чтобы уменьшить временную сложность программы, параллельное выполнение подмассивов выполняется параллельными процессами, работающими для вычисления их частичных сумм, а затем, наконец, главный процесс (корневой процесс) вычисляет сумму этих частичных сумм, чтобы вернуть общую сумму массив.

Примеры:

Ввод: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Выход: сумма массива 55

Ввод: {1, 3, 5, 10, 12, 20, 4, 50, 100, 1000}
Выход: сумма массива 1205

Примечание. Для выполнения следующей программы в вашей системе Linux должен быть установлен MPI. Для получения подробной информации, пожалуйста, обратитесь к MPI - Упрощение распределенных вычислений.

Скомпилируйте и запустите программу, используя следующий код:

mpicc имя_программы.c -o файл_объекта
mpirun -np [количество процессов] ./object_file

Ниже приведена реализация указанной выше темы:




#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// size of array
#define n 10
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Temporary array for slave process
int a2[1000];
int main( int argc, char * argv[])
{
int pid, np,
elements_per_process,
n_elements_recieved;
// np -> no. of processes
// pid -> process id
MPI_Status status;
// Creation of parallel processes
MPI_Init(&argc, &argv);
// find out process ID,
// and how many processes were started
MPI_Comm_rank(MPI_COMM_WORLD, &pid);
MPI_Comm_size(MPI_COMM_WORLD, &np);
// master process
if (pid == 0) {
int index, i;
elements_per_process = n / np;
// check if more than 1 processes are run
if (np > 1) {
// distributes the portion of array
// to child processes to calculate
// their partial sums
for (i = 1; i < np - 1; i++) {
index = i * elements_per_process;
MPI_Send(&elements_per_process,
1, MPI_INT, i, 0,
MPI_COMM_WORLD);
MPI_Send(&a[index],
elements_per_process,
MPI_INT, i, 0,
MPI_COMM_WORLD);
}
// last process adds remaining elements
index = i * elements_per_process;
int elements_left = n - index;
MPI_Send(&elements_left,
1, MPI_INT,
i, 0,
MPI_COMM_WORLD);
MPI_Send(&a[index],
elements_left,
MPI_INT, i, 0,
MPI_COMM_WORLD);
}
// master process add its own sub array
int sum = 0;
for (i = 0; i < elements_per_process; i++)
sum += a[i];
// collects partial sums from other processes
int tmp;
for (i = 1; i < np; i++) {
MPI_Recv(&tmp, 1, MPI_INT,
MPI_ANY_SOURCE, 0,
MPI_COMM_WORLD,
&status);
int sender = status.MPI_SOURCE;
sum += tmp;
}
// prints the final sum of array
printf ( "Sum of array is : %d " , sum);
}
// slave processes
else {
MPI_Recv(&n_elements_recieved,
1, MPI_INT, 0, 0,
MPI_COMM_WORLD,
&status);
// stores the received array segment
// in local array a2
MPI_Recv(&a2, n_elements_recieved,
MPI_INT, 0, 0,
MPI_COMM_WORLD,
&status);
// calculates its partial sum
int partial_sum = 0;
for ( int i = 0; i < n_elements_recieved; i++)
partial_sum += a2[i];
// sends the partial sum to the root process
MPI_Send(&partial_sum, 1, MPI_INT,
0, 0, MPI_COMM_WORLD);
}
// cleans up all MPI state before exit of process
MPI_Finalize();
return 0;
}

Выход:

Сумма массива 55

Ниже приведен снимок процессов, вычисляющих свои частичные суммы:

Хотите учиться на лучших видео и практических задачах, ознакомьтесь с Базовым курсом C для базового и продвинутого C.