MPI从双数组计算差号

MPI calculate difference sign from double array

本文关键字:计算 数组 MPI      更新时间:2023-10-16

我正在尝试用MPI从双数组计算差号,不需要使用外部行或列,结果可能如下:

阵列内

1 0 1 1

2 1 3 1 4

1 3 1 0 1

2 1-1 1 2

输出阵列

0 0 0 0

0-1 0-1 0

0 1-1 1 0

0 0 0 0

我写了一些代码,但当我试图将b数组写入控制台时,我遇到了访问违规读取位置错误。我是MPI的新手,不知道这段代码是否正确。有什么办法吗?

#include <iostream>
#include <chrono>
#include <mpi.h>
#include <iomanip>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[])
{
int size, rank;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
srand(time(NULL));
int R = 4;
int C = 8;

int **a = new int *[R];
a = new int *[R]; 
a[0] = new int[R*C];
for (int i = 1; i < R; i++)
{
a[i] = &a[0][i*C];
}
if (rank == 0) {
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++) 
{
a[i][j] = (rand() % 10) - 5;
cout << setw(5) << a[i][j] << " ";
}
cout << endl;
}
}

int **b = new int *[R];
b = new int *[R]; 
b[0] = new int[R*C];
for (int i = 1; i < R; i++)
{
b[i] = &b[0][i*C];
}

MPI_Bcast(a, R*C, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
int partR = R / size;
int partC = C / size;
int part = partR * partC*size; 
int *c = new int[part];
int sumF = 0;
int sumS = 0;
int tmp = 0;
int x = 0;
auto start = chrono::high_resolution_clock::now();
for (int i = rank*partR; i <= rank*partR+partR; i++) {
for (int j = rank*partC; j <= rank*partC + partC; j++) {
if (i != 0 && i != R - 1 && j != 0 && j != C - 1) {
sumF = a[i - 1][j - 1] + a[i + 1][j - 1] + a[i - 1][j + 1] + a[i + 1][j + 1];
sumS = a[i - 1][j] + a[i + 1][j] + a[i][j - 1] + a[i][j + 1];
if ((sumF - sumS) > 0)
tmp = 1;
if ((sumF - sumS) < 0)
tmp = -1;
if ((sumF - sumS) == 0)
tmp = 0;
c[x] = tmp;
x++;
}
}
}
MPI_Gather(c, part, MPI_INT, &(b[0][0]), part, MPI_INT, 0, MPI_COMM_WORLD);

auto finish = chrono::high_resolution_clock::now();
chrono::duration<double> elapsed = finish - start;
if (rank == 0) {
cout << endl << "Result: " << endl;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
cout << b[i][j] << " ";
}
cout << endl;
}
cout << endl << "T: " << elapsed.count() << endl;
}

MPI_Finalize();
return 0;
system("PAUSE");
}
MPI_Bcast(a, R*C, MPI_INT, 0, MPI_COMM_WORLD);

这不是在广播2D阵列。这获取int**,将其转换为void*,然后告诉编译器它包含R*C整数。事实并非如此。它包含子数组的地址。

在将来的重构中使用1D数组。没有间接寻址的1D访问更好。

但现在要解决您的问题:

MPI_Bcast(a[0], R*C, MPI_INT, 0, MPI_COMM_WORLD);