Is libGMT 6.0.x or 6.1.1 thread-safe?

I’m trying to use BOOST threads to generate a set of independent plots in parallel using libGMT 6.0.x (or 6.1.1) in my application. Unfortunately the app keeps falling over with segfaults when I do so. A non-threaded version works fine, it’s just slow to step through all the sets of plots.

So, is libGMT thread-safe? If so, how do I need to set it up to run properly in a threaded environment?
Is it almost thread-safe? If so, what do I need to slap locks around to keep from stepping on itself?

If it’s not thread-safe, I’ll have to figure out how to speed things up some other way.

libgmt is not thread-safe but it will depend a bit on what you do if you can get away with things. Do you create separate sessions?

Well, if you make your code generate different API structs for each thread AND make the plotting modules generate different PPID (no idea right now on how to do that), see this recent post and link, then maybe you can generate parallel jobs.
You may also have a look at the movie.c to see what it does to run plotting jobs in parallel.

I discovered a serious drawback related to parallel sessions when GMT is compiled with the fftw multi threaded library: when a session is created, gmt_begins calls gmtlib_fft_initialization, which in turn calls fftwf_init_threads. But fftw thread initialization must be done outside of the parallel part of the program, and therefore the program crashes. Try this testapi_openmp.c program for example:

#include < gmt.h >

#include < omp.h >

int main () {

#pragma omp parallel
{
void *API;

printf("start thread %d\n", omp_get_thread_num());
API = GMT_Create_Session("test", 2, 0, NULL);
GMT_Destroy_Session(API);
printf("end thread %d\n", omp_get_thread_num());

}

}

It crashes most of the time with a segmentation fault. Valgrind says:

==21457== Invalid read of size 1 ==21457== at 0x6C3FC2A: fftwf_hash (in /usr/lib/x86_64-linux-gnu/libfftw3f.so.3.5.8) ==21457== by 0x6C4070D: ??? (in /usr/lib/x86_64-linux-gnu/libfftw3f.so.3.5.8) ==21457== by 0x6C46B77: ??? (in /usr/lib/x86_64-linux-gnu/libfftw3f.so.3.5.8) ==21457== by 0x6C42FA7: fftwf_solvtab_exec (in /usr/lib/x86_64-linux-gnu/libfftw3f.so.3.5.8) ==21457== by 0x6D07158: fftwf_configure_planner (in /usr/lib/x86_64-linux-gnu/libfftw3f.so.3.5.8) ==21457== by 0x6D0A887: fftwf_the_planner (in /usr/lib/x86_64-linux-gnu/libfftw3f.so.3.5.8) ==21457== by 0x6E2E4CC: fftwf_init_threads (in /usr/lib/x86_64-linux-gnu/libfftw3f_threads.so.3.5.8) ==21457== by 0x48D8CE6: gmtlib_fft_initialization (in /usr/local/soft_geophy/gmt/gmt-6.2.0/lib/libgmt.so.6.2.0) ==21457== by 0x49A76F3: gmt_begin (in /usr/local/soft_geophy/gmt/gmt-6.2.0/lib/libgmt.so.6.2.0) ==21457== by 0x488B4B4: GMT_Create_Session (in /usr/local/soft_geophy/gmt/gmt-6.2.0/lib/libgmt.so.6.2.0) ==21457== by 0x1091D9: main._omp_fn.0 (in /home/sarzeaud/18AC07-MCO_CTGeoS/tests-gmt6/testapi_openmp) ==21457== by 0x4D8179D: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0) ==21457== Address 0x0 is not stack'd, malloc'd or (recently) free'd

and that’s how I found out this could be due to fftw. Perhaps gmtlib_fft_initializatioon and gmtlib_fft_cleanup should check the thread number before execution, but I am not sure if this is enough. Right now, I compiled GMT without fftw to get rid of this problem.

Olivier

Thanks for pointing this out - using macOS and accelerate means I never really exercise FFTW so never ran into this issue. I will see if I can reproduce it (but at a conference this week).