MPI从双数组计算差异符号
Posted
技术标签:
【中文标题】MPI从双数组计算差异符号【英文标题】:MPI calculate difference sign from double array 【发布时间】:2019-06-09 18:32:55 【问题描述】:我正在尝试使用 MPI 计算双数组的差异符号,无需使用外部行或列,结果可能如下所示:
在数组中
1 0 1 1 1
2 1 3 1 4
1 3 1 0 1
2 1 -1 1 2
输出数组
0 0 0 0 0
0 -1 0 -1 0
0 1 -1 1 0
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");
【问题讨论】:
您正在向另一个进程发送一个指针数组。指针指向进程的地址空间,因此它们不能在另一个进程地址空间中有效。 【参考方案1】:MPI_Bcast(a, R*C, MPI_INT, 0, MPI_COMM_WORLD);
这不是在广播 2D 数组。这需要int**
,将其转换为void*
,然后告诉编译器它包含R*C
整数。它没有。它包含子数组的地址。
在未来的重构中改用一维数组。没有间接的一维访问更好。
但现在要解决您的问题:
MPI_Bcast(a[0], R*C, MPI_INT, 0, MPI_COMM_WORLD);
【讨论】:
谢谢,你是对的,但它应该是 a[0] 还是 a[0][0] 因为它是第一个元素。无论如何,即使我修复它,同样的异常仍然会发生。 可以是a[0]
或&a[0][0]
。收集的发送计数应为 part / size
@folk 是在 MPI 调用期间还是在其他地方?
@GillesGouaillardet 为什么除以size
?
感谢重播,我认为它应该只是部分而不是部分/大小,因为我将整个 c 数组从每个线程获取到 b 数组。我用 recv 指针修复了我的 Gather 函数并正确初始化了 c 数组。但是当我在 4 个线程上运行它时仍然会出现访问冲突,我不确定它在哪里,因为我无法在 4 个线程上进行调试,但它在大 dobule /for/ 块中的某个地方。暂时没有想法。明天检查。以上是关于MPI从双数组计算差异符号的主要内容,如果未能解决你的问题,请参考以下文章