MPI_Gatherv向量下标超出范围

时间:2018-02-21 15:59:47

标签: c++ parallel-processing mpi

大家好,我是MPI的新手,我发现在网站上搜索有一种方法可以收集动态大小的矢量,并收集大小的集合,然后是gatherv。 但是我的代码有问题,这是一个测试我正在运行,看看我是否正确地做了。

int main(int arg, char** argvs) {
MPI_Init(&arg, &argvs);
int size, rank;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

vector<int> vectordata;
if (rank == 1)
    vectordata.push_back(2);
if (rank == 2) {
    vectordata.push_back(1);
    vectordata.push_back(5);
}

int *counts = new int[size];
int nelements = (int)vectordata.size();
// Each process tells the root how many elements it holds
MPI_Gather(&nelements, 1, MPI_INT, counts, 1, MPI_INT, 0, MPI_COMM_WORLD);

// Displacements in the receive buffer for MPI_GATHERV
int *disps = new int[size];
// Displacement for the first chunk of data - 0
for (int i = 0; i < size; i++)
    disps[i] = (i > 0) ? (disps[i - 1] + counts[i - 1]) : 0;

// Place to hold the gathered data
// Allocate at root only
vector<int> alldata;
if (rank == 0)
    // disps[size-1]+counts[size-1] == total number of elements
    alldata = vector<int>(disps[size - 1] + counts[size - 1]);
// Collect everything into the root
MPI_Gatherv(vectordata.data(), nelements, MPI_INT,
    alldata.data(), counts, disps, MPI_INT, 0, MPI_COMM_WORLD);

cout << alldata.size() << endl;
cout << alldata[0] << endl;
cout << alldata[1] << endl;
cout << alldata.back() << endl;

MPI_Finalize();
}

第一个cout应该打印3,而不是打印:
0
0
3
最后3个cout印刷品:
2
1
5

然而在打印之后崩溃说:调试断言失败!矢量下标超出范围。
我认为它与位移有关,但我不确定是什么,如果有人能解释我计算disps [i]的行,那是很好的,因为我从之前的答案得到它并且我不完全明白它。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

MPI_Gatherv将所有内容收集到大师级别。所有等级不等于主等级的alldata仍然是空的(因此最初是两个0,以及“调试断言失败!”错误)。将cout s集放在if (rank == 0)块中,或确保在执行cout之前将所有数据广播到其他排名。