When using flann::Index<flann::L2>::knnSearch with OpenMP enabled (8 threads in flannParam.cores), if another OpenMP parallelism clause is defined, I might receive segmentation fault, e.g.:
void someFunction() {
/// some code ....
flannIndex.knnSearch(flann::Matrix<double>(query_data, point_num, 2),
nearestIdxMat, nearestDistMat, KNN, flannParam
);
/// ... some other code here
#pragma omp parallel num_threads(8)
{
#pragma omp for reduction(+:filtered_num, error, trans_error)
for (int i = 0; i < point_num; i++) {
const auto& [err, trans_err] = icpSolution(knnIdx, knnDist, nnp,
isValid, max_dist, i, all_change_ts, all_previous_ts, all_trans_weights);
if (err >= 0.0 && trans_error >= 0.0) {
error += err;
trans_error += trans_err;
filtered_num += 1;
}
}
}
/// some code ....
}
The code above will result in: computation failure of function knnSearch. The elements in knn id matrix (in the code above:nearestIdxMat) are all wrong. Note that:
There is no data race or read-write conflict in my code (I suppose), the output of knnSearch is used in function icpSolution, which is a const class member function and all the inputs/outputs of it are guaranteed thread safety.
GDB indicates behaviors like this: it seems like there are multiple someFunction() on the run, there are times that: after knnSearch() returned logically (as someFunction() is logically serialized), icpSolution() would still have race condition yet icpSolution() never writes in flann-related data.
There is actually solution to the seg fault above: when I add #pragma omp critical to the place where I call someFunction(), the problem is resolved even though I think it is not elegant and makes no sense at all.
There is some complement information generated from ThreadSanitizer
ThreadSanitizer Output
When using flann::Index<flann::L2>::knnSearch with OpenMP enabled (8 threads in flannParam.cores), data race warning always presents.
Note that: in this situation, OpenMP is used only in flann::Index<flann::L2<double>>::knnSearch, no other openmp clause is used.
Problem
segmentation fault
, e.g.:The code above will result in: computation failure of function knnSearch. The elements in knn id matrix (in the code above:
nearestIdxMat
) are all wrong. Note that:icpSolution
, which is a const class member function and all the inputs/outputs of it are guaranteed thread safety.someFunction()
on the run, there are times that: afterknnSearch()
returned logically (assomeFunction()
is logically serialized),icpSolution()
would still have race condition yeticpSolution()
never writes in flann-related data.#pragma omp critical
to the place where I callsomeFunction()
, the problem is resolved even though I think it is not elegant and makes no sense at all.ThreadSanitizer
ThreadSanitizer Output
data race
warning always presents.Note that: in this situation, OpenMP is used only in
flann::Index<flann::L2<double>>::knnSearch
, no other openmp clause is used.SUMMARY: ThreadSanitizer: data race /usr/include/c++/7/bits/basic_string.h:172 in std::__cxx11::basic_string<char, std::char_traits, std::allocator >::_M_length(unsigned long)