矩阵每个元素都是其上下左右四个元素的平均值,矩阵四个边界的值不变。请使用MPI设计一个求该矩阵中所有值的程序。对数组赋初值,边界赋为8,内部赋为0。
时间: 2023-11-28 22:50:09 浏览: 22
下面是使用MPI实现该程序的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define ROWS 100
#define COLS 100
#define TAG 0
int main(int argc, char *argv[]) {
int rank, size, i, j, iter;
float **matrix, **new_matrix, **temp;
MPI_Request req[8];
MPI_Status status[8];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int rows_per_process = ROWS / size;
int rows_last_process = ROWS - (size - 1) * rows_per_process;
matrix = (float **) malloc((rows_per_process + 2) * sizeof(float *));
new_matrix = (float **) malloc((rows_per_process + 2) * sizeof(float *));
for (i = 0; i < rows_per_process + 2; i++) {
matrix[i] = (float *) malloc(COLS * sizeof(float));
new_matrix[i] = (float *) malloc(COLS * sizeof(float));
}
// initialize matrix
for (i = 1; i <= rows_per_process; i++) {
for (j = 0; j < COLS; j++) {
matrix[i][j] = 0;
new_matrix[i][j] = 0;
}
}
for (j = 0; j < COLS; j++) {
matrix[0][j] = 8;
new_matrix[0][j] = 8;
matrix[rows_per_process + 1][j] = 8;
new_matrix[rows_per_process + 1][j] = 8;
}
// update matrix
for (iter = 0; iter < 100; iter++) {
if (rank == 0) {
for (j = 0; j < COLS; j++) {
new_matrix[1][j] = (matrix[0][j] + matrix[1][j] + matrix[2][j] + matrix[1][j - 1] + matrix[1][j + 1]) / 5;
}
MPI_Isend(&new_matrix[1][0], COLS, MPI_FLOAT, rank + 1, TAG, MPI_COMM_WORLD, &req[0]);
MPI_Irecv(&new_matrix[rows_per_process + 1][0], COLS, MPI_FLOAT, rank + 1, TAG, MPI_COMM_WORLD, &req[1]);
MPI_Waitall(2, req, status);
} else if (rank == size - 1) {
for (j = 0; j < COLS; j++) {
new_matrix[rows_per_process][j] = (matrix[rows_per_process - 1][j] + matrix[rows_per_process][j] + matrix[rows_per_process + 1][j] + matrix[rows_per_process][j - 1] + matrix[rows_per_process][j + 1]) / 5;
}
MPI_Isend(&new_matrix[rows_per_process][0], COLS, MPI_FLOAT, rank - 1, TAG, MPI_COMM_WORLD, &req[0]);
MPI_Irecv(&new_matrix[0][0], COLS, MPI_FLOAT, rank - 1, TAG, MPI_COMM_WORLD, &req[1]);
MPI_Waitall(2, req, status);
} else {
for (j = 0; j < COLS; j++) {
new_matrix[1][j] = (matrix[0][j] + matrix[1][j] + matrix[2][j] + matrix[1][j - 1] + matrix[1][j + 1]) / 5;
new_matrix[rows_per_process][j] = (matrix[rows_per_process - 1][j] + matrix[rows_per_process][j] + matrix[rows_per_process + 1][j] + matrix[rows_per_process][j - 1] + matrix[rows_per_process][j + 1]) / 5;
}
MPI_Isend(&new_matrix[1][0], COLS, MPI_FLOAT, rank + 1, TAG, MPI_COMM_WORLD, &req[0]);
MPI_Irecv(&new_matrix[rows_per_process + 1][0], COLS, MPI_FLOAT, rank + 1, TAG, MPI_COMM_WORLD, &req[1]);
MPI_Isend(&new_matrix[rows_per_process][0], COLS, MPI_FLOAT, rank - 1, TAG, MPI_COMM_WORLD, &req[2]);
MPI_Irecv(&new_matrix[0][0], COLS, MPI_FLOAT, rank - 1, TAG, MPI_COMM_WORLD, &req[3]);
MPI_Waitall(4, req, status);
}
// update internal rows
for (i = 2; i <= rows_per_process - 1; i++) {
for (j = 0; j < COLS; j++) {
new_matrix[i][j] = (matrix[i - 1][j] + matrix[i][j] + matrix[i + 1][j] + matrix[i][j - 1] + matrix[i][j + 1]) / 5;
}
}
// swap matrix and new_matrix
temp = matrix;
matrix = new_matrix;
new_matrix = temp;
}
// gather matrix
if (rank == 0) {
for (i = 1; i <= rows_per_process; i++) {
for (j = 0; j < COLS; j++) {
matrix[i][j] = new_matrix[i][j];
}
}
for (i = 1; i < size; i++) {
if (i == size - 1) {
MPI_Recv(&matrix[i * rows_per_process][0], rows_last_process * COLS, MPI_FLOAT, i, TAG, MPI_COMM_WORLD, &status[0]);
} else {
MPI_Recv(&matrix[i * rows_per_process][0], rows_per_process * COLS, MPI_FLOAT, i, TAG, MPI_COMM_WORLD, &status[0]);
}
}
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%f ", matrix[i][j]);
}
printf("\n");
}
} else {
if (rank == size - 1) {
MPI_Send(&new_matrix[1][0], rows_last_process * COLS, MPI_FLOAT, 0, TAG, MPI_COMM_WORLD);
} else {
MPI_Send(&new_matrix[1][0], rows_per_process * COLS, MPI_FLOAT, 0, TAG, MPI_COMM_WORLD);
}
}
MPI_Finalize();
return 0;
}
```
该程序将矩阵分成多个部分,每个进程负责处理其中的一部分。每个进程在每次迭代中计算出自己部分中所有元素的新值,并与相邻进程交换边界行的数据。最后,主进程将所有部分的矩阵合并,并输出结果。
相关推荐
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)