2013-01-12 34 views
1

我搜索了很多解释,但我想我无法弄清楚我该如何做到这一点。我想要做这样的事情: 使用主处理器,我创建了一个动态二维数组。然后我想;MPI向其他处理器广播动态2D阵列

1-将此数组发送到其他处理器。并且每个处理器打印这个二维数组。012-2-将此数组的一部分发送给其他人。并且每个处理器将其部件打印到屏幕上。

例如;我有2D阵列11 * 11和4个处理器。等级0是主人。其他人是奴隶。对于第一种情况,我想将所有数组发送到1级,2级和3级。而对于第二种情况,我想将行分享给从机。 11/3 = 3.因此,等级1取3行,等级2取3行,等级3取5行。

这里是我的代码:

int processorID; 
int numberOfProcessors; 


int main(int argc, char* argv[]){ 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD ,&numberOfProcessors); 
    MPI_Comm_rank(MPI_COMM_WORLD ,&processorID); 

    double **array; 

    if(MASTER){ 
     array = (double**) malloc(11*sizeof(double *)); 
     for(i=0; i<11; i++){ 
      array[i] = (double *) malloc(11*sizeof(double)); 
     } 

     for(i=0; i<11; i++){ 
      for(j=0; j<11; j++){ 
       array[i][j] = i*j; 
      } 

     } 
    } 
    MPI_Bcast(array, 11*11, MPI_DOUBLE, 0, MPI_COMM_WORLD); 
    if(SLAVE){ 
     for(i=0; i<11; i++){ 
      for(j=0; j<11; j++){ 
       printf("%f ", array[i][j]); 
      } 

     } 
    } 

    MPI_Finalize(); 
    return 0; 
} 

根据这些链接; MPI_Bcast a dynamic 2d array;我需要创建我的数组为;

if (MASTER){ 

    array = (double**) malloc(121*sizeof(double)) 

     for(i=0; i<11; i++){ 
      for(j=0; j<11; j++){ 
       array[i][j] = i*j; // this is not working. 
      } 
     } 
} 

但如果我这样做,我不能初始化数组中的每个成员。 Inner for循环不起作用。我找不到解决问题的办法。

而对于我的第二个问题,我跟着这个链接sending blocks of 2D array in C using MPI。我想我需要改变if(从)的内部。我应该为每个从处理器创建2D子数组。我需要使用MPI_Scatterv。但我完全无法理解。

int main() { 

    ... 
    ... 

    MPI_Scatterv() // what must be here? 
    if(SLAVE){ 
     if(processorID = numberOfProcessor-1){ 
      subArray = (double**) malloc(5*sizeof(double *)); // beacuse number of row for last processor is 5 
      for(i=0; i<11; i++){ 
       array[i] = (double *) malloc(11*sizeof(double)); 
      } 
     } 
     else { 
      subArray = (double**) malloc(3*sizeof(double *)); 
      for(i=0; i<11; i++){ 
       array[i] = (double *) malloc(11*sizeof(double)); 
      } 
     } 
    } 
} 
+0

什么是您确切的编译器错误信息? –

回答

1

C实际上并没有多维数组。我建议将您的值存储在常规的1D缓冲区中,然后从1D值计算正确的索引。像这样:

double* data = (double*)malloc(sizeof(double)*11*11); 

// Now, to access data[i][j], simply do: 
data[j + i*11] = ...; // this "maps" 2D indices into 1D 

这将免去你所有层次malloc -ing的麻烦,它可以很容易地传递给MPI的API。

+0

我做了你所说的。但现在我得到“进程退出没有调用finalize”错误。这是我的新代码。如果(MASTER){//你说过的话} MPI_Bcast(array,11 * 11,MPI_FLOAT,0,MPI_COMM_WORLD); if(SLAVE){//此处没有任何内容} MPI_Finalize();返回0; }代码在这里结束。但我无法解决它 –

+0

你必须为从机上的阵列分配内存,否则它们将会出现段错误并提前退出。所以分配(但不是填充数组)应该放在'if(MASTER)'部分之前。也许这是问题?否则,检查MPI_Bcast的返回值是否有任何错误代码。 –

1

不能使用指针数组(你被错误地调用“二维数组”),因为每行指针是不可移植到另一个节点的地址空间。

你所报的线性内存分配创建一个二维数组的代码是完全正确的,所有你需要做的是索引存储在row major order,使循环成为:

double* array = (double*) malloc(121*sizeof(double)); 
if (MASTER){ 
    for(i=0; i<11; i++){ 
     for(j=0; j<11; j++){ 
      array[j+i*11] = i*j; // row major indexing here 
     } 
    } 
} 

/* Scatter code follows */ 

你可以放心地将这类数组分散到多个节点。

+0

但我认为,而不是双**,双*应取代它。我对么? –

+0

我做了你所说的。但现在我得到“进程退出没有调用finalize”错误。这是我的新代码。如果(MASTER){//你说过的话} MPI_Bcast(array,11 * 11,MPI_FLOAT,0,MPI_COMM_WORLD); if(SLAVE){//此处没有任何内容} MPI_Finalize();返回0; }代码在这里结束。但我无法解决它 –

+0

对不起,我从你的答案中复制了它,但没有注意到它。看我的编辑 – talonmies