Take the following code:
#include <omp.h>
#include <CCfits/CCfits>
#include <sys/stat.h>
int main ()
{
std::string file ( "somefits.fits" );
std::cout << file << std::endl;
// check if file exists
struct stat bf;
if ( stat(file.c_str(),&bf ) )
{
std::cerr << "Error: the file: " << file << " does not exist " << std::endl;
exit(-1);
}
#pragma omp parallel for schedule (dynamic)
for ( uint i = 0; i<4; ++i )
{
std::unique_ptr<CCfits::FITS> fp (new CCfits::FITS (file, CCfits::Read));
// do something
}
return 0;
}
The first part takes care that the file exists. Then I want to use CCfits::FITS file ( or different files ) in a for loop, that has to be parallel. Running the code without the parallelization line works perfectly.
I run the code differently, look below.
- Why does the parallelization fail in this simple example?
- Why is there 90% SEG. FAULT and 10% OK
- How to fix this?
- Can I fix this?
I. Simply running the code results in 90% SEG. FAULT 10% OK
II. Running the code with valgrind --leak-check=full ./code results in
==6654== by 0x4EC1C11: CCfits::HDUCreator::Make(int, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB490F: CCfits::FITS::readExtensions(bool) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB4FA3: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
==6654== by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6654== by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== Other segment start (thread 2)
==6654== at 0x4C34544: pthread_mutex_unlock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x5C09DA1: fits_store_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x5C15042: ffopen (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x4EB2997: CCfits::FITS::open(CCfits::RWmode) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB4F84: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
==6654== by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6654== by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x62B5181: start_thread (pthread_create.c:312)
==6654== by 0x5923EFC: clone (clone.S:111)
==6654== Other segment end (thread 2)
==6654== at 0x4C338E3: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x5C09E1E: fits_clear_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x5C1066E: ffclos (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x4EB2DE5: CCfits::FITS::close() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB32FD: CCfits::FITS::destroy() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4017E7: std::default_delete<CCfits::FITS>::operator()(CCfits::FITS*) const (unique_ptr.h:67)
==6654== by 0x401680: std::unique_ptr<CCfits::FITS, std::default_delete<CCfits::FITS> >::~unique_ptr() (unique_ptr.h:184)
==6654== by 0x4013EB: main._omp_fn.0 (ccfits_omp.cpp:21)
==6654== by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6654== by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x62B5181: start_thread (pthread_create.c:312)
==6654== by 0x5923EFC: clone (clone.S:111)
==6654==
==6654==
==6654== For counts of detected and suppressed errors, rerun with: -v
==6654== ERROR SUMMARY: 53 errors from 19 contexts (suppressed: 495 from 333)
III. Using valgrind --tool=drd ./code results in the following:
==6654== by 0x4EC1C11: CCfits::HDUCreator::Make(int, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB490F: CCfits::FITS::readExtensions(bool) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB4FA3: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
==6654== by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6654== by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== Other segment start (thread 2)
==6654== at 0x4C34544: pthread_mutex_unlock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x5C09DA1: fits_store_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x5C15042: ffopen (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x4EB2997: CCfits::FITS::open(CCfits::RWmode) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB4F84: CCfits::FITS::FITS(std::string const&, CCfits::RWmode, bool, std::vector<std::string, std::allocator<std::string> > const&) (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4013C4: main._omp_fn.0 (ccfits_omp.cpp:21)
==6654== by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6654== by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x62B5181: start_thread (pthread_create.c:312)
==6654== by 0x5923EFC: clone (clone.S:111)
==6654== Other segment end (thread 2)
==6654== at 0x4C338E3: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x5C09E1E: fits_clear_Fptr (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x5C1066E: ffclos (in /usr/lib/x86_64-linux-gnu/libcfitsio.so.3.340)
==6654== by 0x4EB2DE5: CCfits::FITS::close() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4EB32FD: CCfits::FITS::destroy() (in /usr/lib/x86_64-linux-gnu/libCCfits.so.0.0.0)
==6654== by 0x4017E7: std::default_delete<CCfits::FITS>::operator()(CCfits::FITS*) const (unique_ptr.h:67)
==6654== by 0x401680: std::unique_ptr<CCfits::FITS, std::default_delete<CCfits::FITS> >::~unique_ptr() (unique_ptr.h:184)
==6654== by 0x4013EB: main._omp_fn.0 (ccfits_omp.cpp:21)
==6654== by 0x540C349: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==6654== by 0x4C30E7B: ??? (in /usr/lib/valgrind/vgpreload_drd-amd64-linux.so)
==6654== by 0x62B5181: start_thread (pthread_create.c:312)
==6654== by 0x5923EFC: clone (clone.S:111)
==6654==
==6654==
==6654== For counts of detected and suppressed errors, rerun with: -v
==6654== ERROR SUMMARY: 53 errors from 19 contexts (suppressed: 495 from 333)
Well, you are using a lot of bad practices, and even if I don't know anythings about Fits, I can see:
If Fits is keeping track of the already opened files (which I don't know) it is possible that is not prepared for multithreading.
Sorry for my english.