【问题标题】:MPI Broadcasting dynamic 2D array to other processorsMPI 将动态 2D 阵列广播到其他处理器
【发布时间】:2012-12-26 21:23:40
【问题描述】:

我已经搜索了很多解释,但我想我无法弄清楚我该怎么做这种情况。我想做这样的事情: 使用主处理器,我正在创建一个动态二维数组。那我想;

1- 将此数组发送到其他处理器。每个处理器打印这个二维数组 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.
            }
        }
}

但如果我这样做,我无法初始化数组中的每个成员。内部 for 循环不起作用。我找不到任何方法来解决它。

对于我的第二个问题,我点击了这个链接 sending blocks of 2D array in C using MPI 。我想我需要改变 if(SLAVE) 的内部。我应该为每个从处理器创建 2D subArrays。我需要使用 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));
            }
        }
    }
}

【问题讨论】:

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

标签: c arrays multidimensional-array mpi


【解决方案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 */

您可以安全地将这种数组分散到多个节点。

【讨论】:

  • 但我认为不是 double**,而是 double* 应该取代它。我说的对吗?
  • 我照你说的做了。但现在我得到“进程退出而不调用finalize”错误。这是我的新代码。 if(MASTER){ //你说的 } MPI_Bcast(array, 11*11, MPI_FLOAT, 0, MPI_COMM_WORLD); if(SLAVE){ //这里什么都没有 } MPI_Finalize();返回0; } 代码到此结束。但我无法解决它
  • 是的,抱歉,我从您的答案中复制了该内容而没有注意到它。查看我的编辑
【解决方案2】:

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。

【讨论】:

  • 我照你说的做了。但现在我得到“进程退出而不调用finalize”错误。这是我的新代码。 if(MASTER){ //你说的 } MPI_Bcast(array, 11*11, MPI_FLOAT, 0, MPI_COMM_WORLD); if(SLAVE){ //这里什么都没有 } MPI_Finalize();返回0; } 代码到此结束。但我无法解决它
  • 您必须在从属设备上也为数组分配内存,否则它们会出现段错误并提前退出。所以分配(但不填充数组)应该在if (MASTER)-部分之前。也许这就是问题所在?否则,检查 MPI_Bcast 的返回值是否有任何错误代码。
猜你喜欢
  • 2021-12-20
  • 2012-12-26
  • 2017-07-17
  • 2019-07-10
  • 2014-05-07
  • 2020-07-21
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
相关资源
最近更新 更多