使用数组的C中的MPI - 使用MPI_Send()和MPI_Recv()实现MPI_Scatter()

时间:2015-02-20 12:33:30

标签: c arrays parallel-processing mpi

我正在尝试使用MPI运行矩阵乘法程序。数组'a'和'b'的类型为double,大小为512 * 512。数组'a'将被分散,数组'b'将被广播。矩阵乘法后的最终结果将在数组c [512] [512]中的主进程中收集 我试图使用MPI_Send()和MPI_Recv()函数实现MPI_Scatter(),但我有点陷入无限循环(可能)。 P 是进程数。

double a[512][512], b[512][512], c[512][512];
blksz = 512/P;
if(rank == 0) {
    // Scatter input matrix a, implementation of MPI_Scatter()
    for(j = 1 ; j < P ; j++ ) {
        MPI_Send(&a + j*blksz*N*sizeof(double), blksz*N, MPI_DOUBLE, j, 0, MPI_COMM_WORLD);
    }

    // Broadcast the input matrix b, implementation of MPI_Bcast()
    for(j = 1 ; j < P ; j++ ) {
        MPI_Send(&b, N*N, MPI_DOUBLE, j, 1, MPI_COMM_WORLD);
    }
}
else {
    MPI_Recv(&a, blksz*N, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status);
    MPI_Recv(&b, N*N, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
}

for(i = 0 ; i < blksz; i++) {
    for(j = 0 ; j < N ; j++) {
        c[i][j] = 0;
        for(k = 0 ; k < N ; k++) {
            c[i][j] += a[i][k] * b[k][j];
        }
    }
}

// Gather result, implementation of MPI_Gather()
if(rank != 0) {
    MPI_Send(&c, blksz*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
}
else {
    for(i = 1 ; i < P ; i++) {
        MPI_Recv(&c+i*blksz*N*sizeof(double), blksz*N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, &status);
    }
}

我是一名编程的初学者,但是我整晚都想弄清楚,但无济于事。如果有人能帮助我,我真的很感激。

1 个答案:

答案 0 :(得分:0)

当你发送&a + j*blksize*N*sizeof(double)时,你没有做你想做的事。首先,&aa的地址,它是一个数组数组,不是你想要发送的,你想发送一个指针,或*a(技术上这个是一个数组,但它将隐式地转换为指向所述数组的第一个元素的指针。接下来,在进行指针运算时,您不需要(事实上,不应该)乘以sizeof(type);这将由编译器为您处理。所以你的第一个MPI_Send命令应该是

MPI_Send(*a + j*blksz*N, blksz*N, MPI_DOUBLE, j, 0, MPI_COMM_WORLD);

进行类似的更改(对于所有发送和接收),您的代码应该有效。