我认为将MPI_Scatterv 和MPI_Gatherv 包装在辅助函数中是可行的方法。今天我写了一对这样的包装作为我暑期学校的一部分,如果你仍然需要解决方案,请随时使用它们。
void fillCounts(int rank, int size, int totalCount, int *counts, int *offsets) {
int i;
int n;
int sum;
n = totalCount / size;
for (i = 0; i < size; i++)
counts[i] = n;
for (i = 0; i < totalCount % size; i++)
counts[i] += 1;
sum = 0;
for (i = 0; i < size; i++) {
offsets[i] = sum;
sum += counts[i];
}
}
int scatter01(const void *sendBuf, int totalCount, MPI_Datatype dataType,
void *recvBuf, int *recvCount,
int root, MPI_Comm comm) {
int rank;
int size;
int *counts;
int *offsets;
MPI_Comm_rank(comm, &rank);
MPI_Comm_size(comm, &size);
counts = alloca(size * sizeof(int));
offsets = alloca(size * sizeof(int));
fillCounts(rank, size, totalCount, counts, offsets);
*recvCount = counts[rank];
return MPI_Scatterv(sendBuf, counts, offsets, dataType,
recvBuf, counts[rank, dataType, root, comm);
}
int gather01(void *recvBuf, int totalCount, MPI_Datatype dataType,
const void *sendBuf, int root, MPI_Comm comm) {
int rank;
int size;
int *counts;
int *offsets;
MPI_Comm_rank(comm, &rank);
MPI_Comm_size(comm, &size);
counts = alloca(size * sizeof(int));
offsets = alloca(size * sizeof(int));
fillCounts(rank, size, totalCount, counts, offsets);
return MPI_Gatherv(sendBuf, counts[rank], dataType,
recvBuf, counts, offsets, dataType, root, comm);
}
使用示例:
double globData[N];
double partData[N/size+1];
int n;
scatter01(globData, N, MPI_DOUBLE, partData, &n, 0, MPI_COMM_WORLD);
gather01 (globData, N, MPI_DOUBLE, partData, 0, MPI_COMM_WORLD);