如何使用MPI与C++对广播后的二维数组执行并行求和
现有代码错误修正
- 0号进程给
m、n赋值时错误添加了取地址符,属于语法错误,直接对变量赋值即可 - 二维数组广播逻辑错误:每一行只有
n个元素,原代码写的m*n会导致内存越界,且循环结束括号写反 - 原有
sumProc += 1是无效代码,直接删除即可 - 内存释放逻辑错误:需要先逐行释放二维数组的每一行,再释放一级指针
- 修正广播逻辑后所有进程都能拿到完整二维数组,4个进程刚好各自对应一行,分别计算行和后通过归约得到全局总和
需添加的两行求和代码
在注释位置直接插入以下两行即可:
for (int j = 0; j < n; j++) sumProc += arr[procRank][j];
这里直接用进程编号procRank对应二维数组的行索引,4个进程并行计算4行的和,归约后自动累加得到整个数组的总和。
完整可运行代码
#include <mpi.h> #include <stdio.h> #include <stdlib.h> int main (int argc, char** argv) { int procNum, procRank, m, n; int sumProc = 0, sumAll = 0; int** arr; MPI_Status status; MPI_Init(NULL, NULL); MPI_Comm_size(MPI_COMM_WORLD, &procNum); MPI_Comm_rank(MPI_COMM_WORLD, &procRank); if (procRank == 0) { m = 4; n = 5; } MPI_Bcast(&m, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD); int sample_array[4][5] = { {50, 55, 62, 70, 85}, {35, 42, 45, 47, 49}, {32, 33, 36, 37, 38}, {25, 30, 30, 35, 30} }; arr = new int*[m]; for (int i = 0; i < m; i++) { arr[i] = new int[n]; } if (procRank == 0) { for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { arr[i][j] = sample_array[i][j]; printf("%i ", arr[i][j]); } printf("\n"); } } for (int i = 0; i < m; i++) { MPI_Bcast(arr[i], n, MPI_INT, 0, MPI_COMM_WORLD); } // Need two lines of code here to sum the array (rows and columns) for (int j = 0; j < n; j++) sumProc += arr[procRank][j]; MPI_Reduce(&sumProc, &sumAll, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); if (procRank == 0) { printf("sumAll = %i \n", sumAll); } for (int i = 0; i < m; i++) { delete[] arr[i]; } delete[] arr; MPI_Finalize(); return 0; }
运行后0号进程会输出总和866,符合预期。
内容的提问来源于stack exchange,提问作者Brianna Drew
相关产品推荐
相关产品推荐

