Dan
Dan

Reputation: 2837

Segmentation Fault with MPI_Gather

I am using MPI_Gather for the first time and following some examples but for some reason I am getting a seg fault whenever I call it. The relevant code is here:

    //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);

I've allocated a send buffer and receive buffer like in the example, could anybody shed some light on why I might be getting this error?

Upvotes: 1

Views: 1247

Answers (1)

PaulMcKenzie
PaulMcKenzie

Reputation: 35440

Your code has two issues, one that needs to be fixed, and another that will clean up your code. Also, since we really don't know what the values of "j" are, then all I can do is assume that these values are valid.

The issues are as follows:

Issue 1: Calling free() on data allocated with new[].

Never mix allocation and deallocation functions like this. If you allocate with new[], you deallocate using delete[], not free(), and not delete(non-array delete).

Issue 2: Using new[] when there is no need to use it.

You can replace all of those calls to new[] with std::vector. Here is a rewrite of your code snippet using vector:

 //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);

There are now no calls to new[], no (erroneous) calls to free(). There is very little, if any pointer usage. Since the vector knows how to destroy itself, there are no memory leaks.

Upvotes: 1

Related Questions