【问题标题】:Segmentation Fault with MPI_GatherMPI_Gather 的分段错误
【发布时间】:2014-04-19 22:46:40
【问题描述】:

我第一次使用 MPI_Gather 并遵循一些示例,但由于某种原因,每当我调用它时,我都会遇到 seg 错误。相关代码在这里:

    //Get the top N matches for each node
    for (int j = 0; j < send_counts[id]; j++)
    {   
        data = read_file(my_dir + files[rec_buf[j]]);
        temp_results = circularSubvectorMatch(test_vectors[i], data, N); 
        results.insert(results.end(), temp_results.begin(), temp_results.end());
    }   

    std::sort(results.begin(), results.end(), sort_function);
    results.resize(N);

    //Send the N dissimilarities from each node to the root process and let it figure out
    //the Nth best one overall
    float *best_times = new float[N];
    for (int j = 0; j < N; j++)
    {   
        best_times[j] = results[j].dissimilarity;
    }   

    MPI_Barrier(MPI_COMM_WORLD);

    float *all_dissimilarities = NULL;
    if (id == 0)
    {   
       float *all_dissimilarities = new float[N * procs];
    }   

    MPI_Gather(best_times, N, MPI_FLOAT, all_dissimilarities, N, MPI_FLOAT, 0, MPI_COMM_WORLD);
    float *nth_best;
    if (id == 0)
    {
        std::sort(all_dissimilarities, all_dissimilarities + N * procs - 1);
        *nth_best = all_dissimilarities[N-1];
        *nth_best = 1.0;
    }
    MPI_Bcast(nth_best, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);

    cout << "My id is " << id << "and I received: " << *nth_best << endl;

    //each process prints each result it has that is better than or equal
    //to the Nth best result calculated by the root process


    //output search vector and search time

    free(all_dissimilarities);
    free(best_times);
    MPI_Barrier(MPI_COMM_WORLD);

我已经像示例中那样分配了一个发送缓冲区和接收缓冲区,有人能解释一下我为什么会收到这个错误吗?

【问题讨论】:

  • 我很好奇你为什么在代码中的某些地方使用 std::vector ,但不要将它用于诸如此类的明显事情:float *best_times = new float[N]; 然后你通过以下方式复杂化问题在分配有new[] 的内存上调用free()。就目前而言,您的代码 sn-p 引入了未定义的行为。
  • 这实际上是我的第一个 C++ 课程,所以我对这门语言有点陌生。这不是段错误的原因吗?
  • 您的代码引入了未定义的行为。这样的代码可能会发生任何事情。我的建议是停止阅读“C”语言书籍或“C”相关材料,并开始阅读 C++ 书籍和材料。此外,由于它是一个 sn-p,我们不知道 j 的值是什么,该 files 数组是否被越界访问等等。
  • 我怀疑这个版本崩溃了,因为你的根进程两次声明了all_dissimilarities;第二次,分配内存的位置(float *all_dissimilarities = new float[N * procs];)在 if 块中,不影响主函数体中定义的all_dissimilarities,它仍然为 NULL。现在为什么下面的矢量版本会崩溃,我不确定...

标签: c++ parallel-processing segmentation-fault openmpi


【解决方案1】:

您的代码有两个问题,一个需要修复,另一个需要清理您的代码。此外,由于我们真的不知道“j”的值是什么,那么我所能做的就是假设这些值是有效的。

问题如下:

问题 1:对使用 new[] 分配的数据调用 free()。

永远不要像这样混合分配和释放功能。如果使用new[] 分配,则使用delete[] 解除分配,而不是free(),而不是delete(非数组删除)。

问题 2:在不需要使用 new[] 时使用它。

您可以用 std::vector 替换所有对 new[] 的调用。这是使用向量对代码 sn-p 的重写:

 //Get the top N matches for each node
#include <vector>
//...
typedef std::vector<float> FloatArray;
//...
for (int j = 0; j < send_counts[id]; j++)
{   
    data = read_file(my_dir + files[rec_buf[j]]);
    temp_results = circularSubvectorMatch(test_vectors[i], data, N); 
    results.insert(results.end(), temp_results.begin(), temp_results.end());
}   

std::sort(results.begin(), results.end(), sort_function);
results.resize(N);

//Send the N dissimilarities from each node to the root process and let it figure out
//the Nth best one overall
FloatArray best_times(N);
for (int j = 0; j < N; j++)
    best_times[j] = results[j].dissimilarity;

MPI_Barrier(MPI_COMM_WORLD);

float *pFirst = NULL;
FloatArray all_dissimilarities;
if (id == 0)
{
   all_dissimilarities.resize(N * procs);
   pFirst = &all_disimilarities[0];
}

MPI_Gather(&best_times[0], N, MPI_FLOAT, pFirst, N, MPI_FLOAT, 0, MPI_COMM_WORLD);
float nth_best;
if (id == 0)
{
    std::sort(all_dissimilarities.begin(), all_dissimilarities.end());
    nth_best = all_dissimilarities.back();
    nth_best = 1.0;
}
MPI_Bcast(&nth_best, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);
cout << "My id is " << id << "and I received: " << nth_best << endl;
MPI_Barrier(MPI_COMM_WORLD);

现在没有对 new[] 的调用,也没有对 free() 的(错误的)调用。如果有指针使用,则很少。由于向量知道如何销毁自己,因此不会发生内存泄漏。

【讨论】:

  • 我做了这些更改,我同意他们肯定会纠正其他错误,但不幸的是他们没有解决我的段错误问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-20
  • 2020-09-09
  • 2017-01-11
  • 2016-05-25
  • 1970-01-01
相关资源
最近更新 更多