我有np
个进程和np
个不同长度的不同数组。我必须将其中一个发送到每个进程(对所有进程重复相同)。其中一个np
部分应保留在该流程上。
在3个流程的情况下应该是:
p0
有[A0 B0 C0]
,最终应该有[A0 A1 A2]
p1
有[A1 B1 C1]
,最终应该有[B0 B1 B2]
p2
有[A2 B2 C2]
,最终应该有[C0 C1 C2]
我的想法是首先收集所有长度,然后分配内存,最后执行MPI_gatherv
操作,同时更改根等级,如共享信息:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc, char **argv) {
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if(size!=3){
MPI_Finalize();
printf("execution with np = 3 only\n");
return 1;
}
int a[5],b[5],c[5],len_a,len_b,len_c;
if(rank == 0){
a[0] = 0 ;
b[0] = 30;
c[0] = 60;
len_a = len_b = len_c = 1;
//a,b,c can have different lengths
}
else if(rank == 1){
a[0] = 1 ; a[1] = 11;
b[0] = 31; b[1] = 41;
c[0] = 61; c[1] = 71;
len_a = len_b = len_c = 2;
//a,b,c can have different lengths
}
else if(rank == 2){
a[0] = 2 ; a[1] = 12; a[2] = 22;
b[0] = 32; b[1] = 42; b[2] = 52;
c[0] = 62; c[1] = 72; c[2] = 82;
len_a = len_b = len_c = 3;
//a,b,c can have different lengths
}
/*
At the end I should have
rank 0 : a = { 0 | 1 11 | 2 12 22 }
rank 1 : b = { 30 | 31 41 | 32 42 52 }
rank 2 : c = { 60 | 61 71 | 62 72 82 }
*/
int lengths[3];
int tot_length;
/*
* we Gather the lengths for every process as root
*/
int mylen,i,root = 0;
for(i=0;i<3;i++){
root = i;
mylen = rank + 1;
MPI_Gather(&mylen,
1,
MPI_INT,
lengths,
1,
MPI_INT,
root,
MPI_COMM_WORLD);
}
/*
calculate tot_length of my elem array
and determine the disp vector
*/
int displs[3];
displs[0] = 0;
tot_length = lengths[0];
for(i=1;i<3;i++){
displs[i] = displs[i-1] + lengths[i-1];
tot_length += lengths[i];
}
printf("rank %d lengths = %d %d %d displs = %d %d %d \n", rank, \
lengths[0],lengths[1],lengths[2], \
displs[0],displs[1],displs[2]);
int *elem = malloc(tot_length * sizeof(int));
int myvec[5];
int j;
for(i=0;i<3;i++){
root = i;
if(root == 0){
for(j=0;j<5;j++)
myvec[j]=a[j];
}
else if(root == 1){
for(j=0;j<5;j++)
myvec[j]=b[j];
}
else if(root == 2){
for(j=0;j<5;j++)
myvec[j]=c[j];
}
MPI_Gatherv(myvec,
mylen,
MPI_INT,
elem,
lengths,
displs,
MPI_INT,
root,
MPI_COMM_WORLD);
}
printf("rank %d elem : ",rank);
for(i=0;i<tot_length;i++){
printf("%d ", elem[i]);
}
printf("\n");
MPI_Finalize();
return 0;
}
有没有更好的方法或有效的内置功能来执行此操作?