Я думаю, что это проще всего проиллюстрировать с помощью некоторого кода. Как объяснил Жиль, MPI позаботится обо всех коммуникациях и сократит процессы - все, что вам нужно указать, - это функция парного сравнения. Обратите внимание, что прототип для операции сокращения фиксируется MPI и допускает уменьшение вектора: третий аргумент - это число для длины вектора в каждом процессе ( не число процессов, которое неявно является размер коммуникатора). Кроме некоторых мелких проблем с пустыми и двойными указателями, ваша функция сравнения может быть зарегистрирована как есть и использоваться для операции сокращения:
#include <stdio.h>
#include <mpi.h>
void findminnorm(void *invec, void *inoutvec, int *len, MPI_Datatype *datatype)
{
int i;
double *invecdble = (double *) invec;
double *inoutvecdble = (double *) inoutvec;
for (i=0; i < *len; i++)
{
if (invecdble[i] > 0)
{
if (inoutvecdble[i] > invecdble[i] || inoutvecdble[i] < 0)
{
inoutvecdble[i] = invecdble[i];
}
}
}
}
#define N 2
int main()
{
int i;
double input[N], output[N];
int rank, size;
MPI_Op MPI_MINNORM;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Op_create(findminnorm, 1, &MPI_MINNORM);
for (i=0; i < N; i++)
{
input[i] = (-size/2+rank+i)*(i+1);
printf("On rank %d, input[%d] = %f\n", rank, i, input[i]);
output[i] = -1;
}
MPI_Allreduce(&input, &output, N, MPI_DOUBLE, MPI_MINNORM, MPI_COMM_WORLD);
for (i=0; i < N; i++)
{
printf("On rank %d, output[%d] = %f\n", rank, i, output[i]);
}
MPI_Finalize();
}
Инициализация немного случайна, но я думаю, что она служит для иллюстрации (хотя ваша функция сравнения должна действительно справляться с ситуацией, когда все входы отрицательны):
mpirun -n 5 ./minnorm | grep input | sort
On rank 0, input[0] = -2.000000
On rank 0, input[1] = -2.000000
On rank 1, input[0] = -1.000000
On rank 1, input[1] = 0.000000
On rank 2, input[0] = 0.000000
On rank 2, input[1] = 2.000000
On rank 3, input[0] = 1.000000
On rank 3, input[1] = 4.000000
On rank 4, input[0] = 2.000000
On rank 4, input[1] = 6.000000
mpirun -n 5 ./minnorm | grep output | sort
On rank 0, output[0] = 1.000000
On rank 0, output[1] = 2.000000
On rank 1, output[0] = 1.000000
On rank 1, output[1] = 2.000000
On rank 2, output[0] = 1.000000
On rank 2, output[1] = 2.000000
On rank 3, output[0] = 1.000000
On rank 3, output[1] = 2.000000
On rank 4, output[0] = 1.000000
On rank 4, output[1] = 2.000000