Може да прекалявате с това - в случая по-горе можете да го направите с едно намаление и една двойка изпращане/приемане:
#include <stdio.h>
#include <mpi.h>
int main(int argc, char **argv) {
int data[2], result[2];
int rank, size;
const int amaster=0, bmaster=1;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
data[0] = 2*rank;
data[1] = 3*rank;
MPI_Reduce(data, result, 2, MPI_INT, MPI_SUM, amaster, MPI_COMM_WORLD);
if (rank == amaster) {
int tota = result[0];
printf("%d: Total a = %d, expected = %d\n", rank, tota, 2*size*(size-1)/2);
MPI_Send(&(result[1]), 1, MPI_INT, bmaster, 0, MPI_COMM_WORLD);
}
if (rank == bmaster) {
int totb;
MPI_Recv(&totb, 1, MPI_INT, amaster, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("%d: Total b = %d, expected = %d\n", rank, totb, 3*size*(size-1)/2);
}
MPI_Finalize();
return 0;
}
И естественото обобщение за множество части от данни е разсейването, така че вашата интуиция за MPI_Reduce_scatter
е правилна, но тук, тъй като двете групи задачи се припокриват (така че не можете да използвате интеркомуникатор), но не са еднакви, ще имате за да направите намаление, последвано от скатер, като скатерът ще трябва да бъде на друг комуникатор:
#include <stdio.h>
#include <mpi.h>
int main(int argc, char **argv) {
const int ndata = 5;
int data[ndata], result[ndata];
int rank, size;
const int amaster=0;
MPI_Comm scattercomm;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size < ndata) {
if (rank == 0) fprintf(stderr,"Too few ranks; exiting\n");
MPI_Abort(MPI_COMM_WORLD,1);
}
for (int i=0; i<ndata; i++)
data[i] = (i+2)*rank;
/* create scatter communicator; all of comm world must participate */
MPI_Group basegrp, scattergrp;
MPI_Comm_group(MPI_COMM_WORLD, &basegrp);
int mpiranks[ndata];
for (int i=0; i<ndata; i++)
mpiranks[i] = i;
MPI_Group_incl(basegrp, ndata, mpiranks, &scattergrp);
MPI_Comm_create(MPI_COMM_WORLD, scattergrp, &scattercomm);
MPI_Reduce(data, result, ndata, MPI_INT, MPI_SUM, amaster, MPI_COMM_WORLD);
if (rank < ndata) {
int item;
MPI_Scatter(result, 1, MPI_INT, &item, 1, MPI_INT, amaster, scattercomm);
printf("%d: Total = %d, expected = %d\n", rank, item, (rank+2)*size*(size-1)/2);
}
MPI_Finalize();
return 0;
}
person
Jonathan Dursi
schedule
19.06.2014