【发布时间】:2016-03-03 18:58:03
【问题描述】:
我在使用 MPI 程序时遇到了一个奇怪的问题。部分代码应该只由根(进程零)执行,但进程零似乎执行了两次。例如,
root = 0;
if (rank == root) {
cout << "Hello from process " << rank << endl;
}
给予
来自进程 0 的问候
来自进程 0 的问候
这似乎只在我使用 16 个或更多进程时才会发生。我已经尝试调试了好几天,但没有成功。
由于我不知道为什么会这样,我想我必须在这里复制我的整个代码。我做得很好很清楚。目标是将两个矩阵相乘(简化假设)。问题发生在最后的if 块中。
#include <iostream>
#include <cstdlib>
#include <cmath>
#include "mpi.h"
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 2) {
cout << "Use one argument to specify the N of the matrices." << endl;
return -1;
}
int N = atoi(argv[1]);
int A[N][N], B[N][N], res[N][N];
int i, j, k, start, end, P, p, rank;
int root=0;
MPI::Status status;
MPI::Init(argc, argv);
rank = MPI::COMM_WORLD.Get_rank();
P = MPI::COMM_WORLD.Get_size();
p = sqrt(P);
/* Designate the start and end position for each process. */
start = rank * N/p;
end = (rank+1) * N/p;
if (rank == root) { // No problem here
/* Initialize matrices. */
for (i=0; i<N; i++)
for (j=0; j<N; j++) {
A[i][j] = N*i + j;
B[i][j] = N*i + j;
}
cout << endl << "Matrix A: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << A[i][j];
if(j==N-1)
cout << endl;
}
cout << endl << "Matrix B: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << B[i][j];
if(j==N-1)
cout << endl;
}
}
/* Broadcast B to all processes. */
MPI::COMM_WORLD.Bcast(B, N*N, MPI::INT, 0);
/* Scatter A to all processes. */
MPI::COMM_WORLD.Scatter(A, N*N/p, MPI::INT, A[start], N*N/p, MPI::INT, 0);
/* Compute your portion of the final result. */
for(i=start; i<end; i++)
for(j=0; j<N; j++) {
res[i][j] = 0;
for(k=0; k<N; k++)
res[i][j] += A[i][k]*B[k][j];
}
MPI::COMM_WORLD.Barrier();
/* Gather results form all processes. */
MPI::COMM_WORLD.Gather(res[start], N*N/p, MPI::INT, res, N*N/p, MPI::INT, 0);
if (rank == root) { // HERE is the problem!
// This chunk executes twice in process 0
cout << endl << "Result of A x B: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << res[i][j];
if(j == N-1)
cout << endl;
}
}
MPI::Finalize();
return 0;
}
当我使用 P = 16 和两个 4x4 矩阵运行程序时:
>$ mpirun -np 16 ./myprog 4
Matrix A:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Matrix B:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Result of A x B:
6366632 0 0 0
-12032 32767 0 0
0 0 -1431597088 10922
1 10922 0 0
Result of A x B:
56 62 68 74
152 174 196 218
248 286 324 362
344 398 452 506
为什么要打印出第一个结果? 如果有人愿意帮助我,我将不胜感激。
【问题讨论】:
-
对于这么小的 n,
N*N/p将评估为 0。这似乎是一个问题。你试过N>16,P=16吗? -
这似乎给了我一个分段错误。我不认为
N*N/p评估为零;添加打印语句显示它为 4,P=16 和 N=4。通知p = sqrt(P)。
标签: c++ parallel-processing mpi