0

I'm getting a very weird segmentation fault on the following loop. The goal is to have each processor do some checks of x/y points which are stored on the following vectors

Just to clarify: This is a multi-processor code not multi thread. This is how I'm getting the rank:

 int my_rank = Utilities::MPI::this_mpi_process(mpi_communicator); 

 std::vector<std::vector<double> > Xcoord(n_proc);
 std::vector<std::vector<double> > Ycoord(n_proc);

The Xcoord[i] is a vector of x coordinates that come from the i processor and the current processor will do some checks on them, which I'm not including them below:

The code loops through the n processors, first check if it has any information about the paarticular point, and if yes, saves the id of the point and the id of the processor.

std::vector<std::vector<int> > which_point(n_proc);
std::vector<std::vector<int> > which_proc(n_proc);
for (int i = 0; i < n_proc; ++i){
     if (i == my_rank) continue;
     for (unsigned int j = 0; j < Xcoord[i].size(); ++j){
         bool yit = getYiterator(yxmap, Ycoord[i][j], itY);
         if (yit){
              bool xit = getXiterator(itY->second, Xcoord[i][j], itX);
              if (xit){
                    itZ = itX->second.zmap.begin();
                    for (; itZ != itX->second.zmap.end(); ++itZ){
                        which_point[my_rank].push_back(j);
                        which_proc[my_rank].push_back(i);
                    }
              }
         }
    } 
}

(In the innermost loop the itX->second.zmap.size() is 3)

When I run the code in one processor everything works fine.

When I do so with 4 processors I'm getting segmentation faults.

If I remove one of the two lines

which_proc[my_rank].push_back(i); or 
which_point[my_rank].push_back(j); 

the code works even with 4 processors.

I've also noticed that the segmentation fault is always associated with rank 2. So if I set the condition if (my_rank != 2) in front of one of the two above lines the code works in 4 processors.

I've seen few posts on this issue but in most cases the errors occurred from empty pointers passing to push_back().

Here I'm pushing back just an integer number, which to me obviously exists when it's pushed to a vector.

Any idea how I could catch this error??

Thank you

giorgk
  • 109
  • 1
  • 11
  • 1
    Um, you talked about doing the code with 4 processors. Do you mean you're parallelising the outer loop with something like OpenMP? If that's the case, I'd expect those lines to segfault because they are operating on the same array. Did you mean to use `which_point[i]` instead of `which_point[my_rank]`? – paddy May 26 '14 at 00:54
  • The vectors which_point are different on each processor. This should be which_point[my_rank]. – giorgk May 26 '14 at 01:03
  • Show your parallelism code. You admit yourself that the single threaded works correctly, so we're forced to guess how the error is introduced. Your use of the term "rank" makes me think you're using MPI, and if so then realize that multi-*process* is different from multi-*thread*. – Adam May 26 '14 at 01:14
  • @Adam You are correct I'm using MPI. I have made a clarification in the question. Thank you – giorgk May 26 '14 at 01:21
  • and `n_proc` is initialized properly? Can `my_rank` ever equal or be larger than `n_proc` (it shouldn't be, but maybe you have a bug elsewhere). – Adam May 26 '14 at 01:26
  • I'll assume it makes sense for `which_proc` to be size `n_proc` even though you only use the `my_rank`th element. (usually each rank has its own and you want to keep data duplication to a minimum, else you start to limit your scalability) – Adam May 26 '14 at 01:28
  • I'm doing this because after this loop I use MPI_Allgatherv so that which_proc[i] contains info coming from ith – giorgk May 26 '14 at 01:38

1 Answers1

0

The reason most often you end up segfaulting when trying to push_pack concurrently is because in one thread you may try to push_back, the vector is being reallocated (so all iterators are being invalidated), while the other thread tries to push_back to something that is now invalid memory (the other thread "doesn't know" that the vector was reallocated meanwhile, i.e. will use the invalid iterators).

Possible duplicate of Is std::vector or boost::vector thread safe?

Community
  • 1
  • 1
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • I'm not expert on this, but I believe this is a different situation. The processors do not share memory, at least that's my intention. In addition the vectors `which_proc` at the end of the loop should have different sizes – giorgk May 26 '14 at 01:14
  • @giorgk I just thought that both `push_back` are done in parallel, i.e `which_proc[my_rank].push_back(i); which_point[my_rank].push_back(j);`, and if this is the case, there is trouble. Also, is this really multi-process code or just multi-threaded? This can make a whole lot of a difference. – vsoftco May 26 '14 at 01:16
  • I've made a clarification in the question. This is a multi-process code. – giorgk May 26 '14 at 01:27