How to set up MP-enabled GMT

Hi guys,

I am calculating free air gravity anomaly using gravprisms on my MacBook Pro (M3 Max, 16 cores). The grid is 4000*600 km with an interval of 2 km. When I run the code I notice that only one core is used for calculation hence it will take a long time to finish the calculation (several days). So I am wondering whether I could set up MP-enabled GMT to make it faster. I already set up the OpenMP on my laptop. What should I do next?

Many thanks for your help!

Hi @geos

you could compile GMT from source - see the Building guide. Then, set up the ConfigUserAdvanced.cmake to enable OpenMP:

# Allow building of OpenMP if compiler supports it
set (GMT_ENABLE_OPENMP TRUE)  

I’m using MacPorts to install the dependencies (homebrew or compiling those from source also works).

Cheers,
Christian

Hi Christian @chhei-s ,

Many thanks for your help! I compiled GMT from source on my laptop following your suggestion. But do I need to include OpenMP when I install GMT (cmake --build . --target install) or use OpenMP when I run the code/script? I re-ran the code after I re-installed GMT but it is still using one core…

Many thanks!

Those grav codes, except gravfft, are never very fast, but days??? Can you show us your command?

And, sorry but Mac & OMP are not exactly friends

Hi @Joaquim ,

Many thanks for the information. Is there any other way to do the MP calculation of gravprisms in GMT without using OMP on Mac? I am sure the command is OK, but the grid is too large…

Many thanks!

A 2000x300 grid does not seem big to me. Again, can you show the command? I would like to try it.

I believe that if you build GMT with GCC than you’ll have OMP on Mac.

(replying from different account)

Hm - I think Joaquim might be right here. I also found this old thread on the forum by @KristofKoch on the same topic that references the issue @Joaquim referred to.

See also this MacOS (Pre-Apple ARM processors) and this link on macos multiprocessing - the latter one says:

Unlike Asahi Linux, macOS doesn’t provide direct access to cores, core types, or clusters, at least not in public APIs. Instead, these are normally managed through Grand Central Dispatch using Quality of Service (QoS) settings, which macOS then uses to determine thread management policies.

Cheers,
Christian

Hi @Joaquim and @chhei @chhei-s ,

Thanks for all the suggestions. I re-built GMT with GCC following below:

Specifically, I created cache.cmake under ~/cache.cmake:

SET ( CMAKE_C_COMPILER "/Library/Developer/CommandLineTools/usr/bin/gcc" CACHE STRING "GNU MP C compiler" )
SET ( CMAKE_CXX_COMPILER "/Library/Developer/CommandLineTools/usr/bin/g++" CACHE STRING "GNU MP C++ compiler" )
SET (CMAKE_C_FLAGS -flax-vector-conversions CACHE STRING "C FLAGS")
SET (CMAKE_C_FLAGS_DEBUG -flax-vector-conversions CACHE STRING "C FLAGS DEBUG")
SET (CMAKE_C_FLAGS_RELEASE -flax-vector-conversions CACHE STRING "C FLAGS RELEASE")
SET (OpenMP_C_FLAGS -flax-vector-conversions CACHE STRING "C FLAGS OPENMP")

Then I

mkdir build
cd build

cmake -DCMAKE_INSTALL_PREFIX=/opt/GMT-6.5. -DCMAKE_BUILD_TYPE=Release -G Ninja -C ~/cache.cmake ..

Then

cmake --build .
cmake --build . --target install

GMT 6.5 was successfully installed. But the code is still using one core…
Did I miss anything?

Many thanks!

1 Like

The recommended way is to create a ConfigUser.cmake from ConfigUserTemplate.cmake in the source cmake directory, but I guess another pointed by -C should work to. But you have not set

set (GMT_ENABLE_OPENMP TRUE)

When I run your command (Windows here and 16 cores) I see my CPU working at > 90% so the OMP must be the responsible for that high CPU usage.

Hi @Joaquim and @chhei @chhei-s ,

Today I tried to add -x option (Limit number of cores used in multi-threaded algorithms (OpenMP required).) in gravprisms to use more cores for calculation:

gmt gravprisms -RTopo.grd -Mh -GFAA.grd Prisms_dz.txt -Ff -Z5000 -x14 -V

But I got an error:
gravprisms [ERROR]: Unrecognized option -x
Does it mean the GMT on my MacBook is not MP-enabled?

When I compiled GMT from source, I created a ConfigUser.cmake:

set (CMAKE_INSTALL_PREFIX "/opt/GMT-6.5.0")
set (GSHHG_ROOT "/path/to/gshhg")
set (DCW_ROOT "/path/to/dcw")
set (CMAKE_C_COMPILER "/opt/homebrew/bin/gcc-12" CACHE STRING "GNU MP C compiler")
set (CMAKE_CXX_COMPILER "/opt/homebrew/bin/gcc++-12" CACHE STRING "GNU MP C++ compiler")
set (CMAKE_C_FLAGS -flax-vector-conversions CACHE STRING "C FLAGS")
set (CMAKE_C_FLAGS_DEBUG -flax-vector-conversions CACHE STRING "C FLAGS DEBUG")
set (CMAKE_C_FLAGS_RELEASE -flax-vector-conversions CACHE STRING "C FLAGS RELEASE")
set (OpenMP_C_FLAGS -flax-vector-conversions CACHE STRING "C FLAGS OPENMP")
set (GMT_USE_THREADS TRUE)
set (GMT_ENABLE_OPENMP TRUE)

I noticed in Paul’s cache.cmake setting (OpenMP support on macOS · Issue #1926 · GenericMappingTools/gmt · GitHub) he used
SET ( CMAKE_C_COMPILER "/opt/local/bin/gcc-mp-9" CACHE STRING "GNU MP C compiler" ) SET ( CMAKE_CXX_COMPILER "/opt/local/bin/g++-mp-9" CACHE STRING "GNU MP C++ compiler" )
Does gcc-mp-9 mean I need to use brew-installed gcc/gcc-mp (is gcc-mp a special version of gcc for MP?) rather than Mac integrated gcc (clang)?
I also added set (GMT_ENABLE_OPENMP TRUE) to ConfigUserAdvanced.cmake.

When I ran cmake .. -G Ninja, I got:

CMake version: 3.29.2
-- The C compiler identification is AppleClang 15.0.0.15000100
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Found UnixCommands: /bin/bash
-- Found Git: /usr/bin/git (found version "2.39.3 (Apple Git-145)")
fatal: not a git repository (or any of the parent directories): .git
-- Searching dependent libraries. This may take a few minutes...
-- Found NETCDF: /opt/homebrew/Cellar/netcdf/4.9.2_1/lib/libnetcdf.dylib
-- Found CURL: /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/lib/libcurl.tbd (found version "8.4.0")
-- Found GDAL: /opt/homebrew/Cellar/gdal/3.8.5_2/lib/libgdal.dylib
-- Found GEOS: /opt/homebrew/Cellar/geos/3.12.1/lib/libgeos_c.dylib (3.12.1
)
-- Could NOT find PCRE (missing: PCRE_INCLUDE_DIR) 
-- Found PCRE2: /opt/homebrew/Cellar/pcre2/10.43/lib/libpcre2-8.dylib
-- Looking for fftwf_plan_with_nthreads in /opt/homebrew/lib/libfftw3f.dylib
-- Looking for fftwf_plan_with_nthreads in /opt/homebrew/lib/libfftw3f.dylib - not found
-- Looking for fftwf_import_wisdom_from_filename
-- Looking for fftwf_import_wisdom_from_filename - found
-- Found FFTW3: /opt/homebrew/lib/libfftw3f.dylib
-- Looking for sgemm_
-- Looking for sgemm_ - not found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Looking for dgemm_
-- Looking for dgemm_ - found
-- Found BLAS: /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/System/Library/Frameworks/Accelerate.framework
-- Looking for cheev_
-- Looking for cheev_ - found
-- Found LAPACK: /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/System/Library/Frameworks/Accelerate.framework;-lm;-ldl
-- Must add compiler flag -DACCELERATE_NEW_LAPACK definition for macOS kernel version 23.2.0
-- Found ZLIB: /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/lib/libz.tbd (found version "1.2.12")
-- Found OpenMP_C: -flax-vector-conversions
-- Found OpenMP: TRUE
-- Found PkgConfig: /opt/homebrew/bin/pkg-config (found version "0.29.2")
-- Found GLIB: /opt/homebrew/Cellar/glib/2.80.0_2/include/glib-2.0;/opt/homebrew/Cellar/glib/2.80.0_2/lib/glib-2.0/include (found version "2.80.0")
-- Found GSHHG: /Users/chong/Downloads/gmt-6.5.0/share/gshhg-gmt
-- Found DCW: /Users/chong/Downloads/gmt-6.5.0/share/dcw-gmt
-- Performing Test HAVE_TRADITIONAL_CPP
-- Performing Test HAVE_TRADITIONAL_CPP - Failed
-- Performing Test HAVE___FUNC__
-- Performing Test HAVE___FUNC__ - Success
-- Performing Test HAVE___FUNCTION__
-- Performing Test HAVE___FUNCTION__ - Success
-- Performing Test HAVE_C_inline
-- Performing Test HAVE_C_inline - Success
-- Looking for io.h
-- Looking for io.h - not found
-- Looking for direct.h
-- Looking for direct.h - not found
-- Looking for process.h
-- Looking for process.h - not found
-- Looking for assert.h
-- Looking for assert.h - found
-- Looking for dirent.h
-- Looking for dirent.h - found
-- Looking for errno.h
-- Looking for errno.h - found
-- Looking for execinfo.h
-- Looking for execinfo.h - found
-- Looking for fcntl.h
-- Looking for fcntl.h - found
-- Looking for signal.h
-- Looking for signal.h - found
-- Looking for stdbool.h
-- Looking for stdbool.h - found
-- Looking for sys/dir.h
-- Looking for sys/dir.h - found
-- Looking for sys/resource.h
-- Looking for sys/resource.h - found
-- Looking for sys/stat.h
-- Looking for sys/stat.h - found
-- Looking for sys/time.h
-- Looking for sys/time.h - found
-- Looking for sys/ucontext.h
-- Looking for sys/ucontext.h - found
-- Looking for unistd.h
-- Looking for unistd.h - found
-- Looking for fcntl
-- Looking for fcntl - found
-- Looking for fopen64
-- Looking for fopen64 - not found
-- Looking for fseeko
-- Looking for fseeko - found
-- Looking for ftello
-- Looking for ftello - found
-- Looking for getpwuid
-- Looking for getpwuid - found
-- Looking for abs
-- Looking for abs - found
-- Looking for llabs
-- Looking for llabs - found
-- Looking for pclose
-- Looking for pclose - found
-- Looking for popen
-- Looking for popen - found
-- Looking for qsort_r
-- Looking for qsort_r - found
-- Performing Test HAVE_QSORT_R_GLIBC
-- Performing Test HAVE_QSORT_R_GLIBC - Failed
-- Looking for strcasecmp
-- Looking for strcasecmp - found
-- Looking for strncasecmp
-- Looking for strncasecmp - found
-- Looking for stricmp
-- Looking for stricmp - not found
-- Looking for strnicmp
-- Looking for strnicmp - not found
-- Looking for strdup
-- Looking for strdup - found
-- Looking for strndup
-- Looking for strndup - found
-- Looking for strsep
-- Looking for strsep - found
-- Looking for strtod
-- Looking for strtod - found
-- Looking for strtok_r
-- Looking for strtok_r - found
-- Looking for strtof
-- Looking for strtof - found
-- Looking for strsignal
-- Looking for strsignal - found
-- Looking for strdup
-- Looking for strdup - found
-- Looking for strsep
-- Looking for strsep - found
-- Looking for basename
-- Looking for basename - found
-- Looking for fileno
-- Looking for fileno - found
-- Looking for setlocale
-- Looking for setlocale - found
-- Looking for snprintf
-- Looking for snprintf - found
-- Looking for vsnprintf
-- Looking for vsnprintf - found
-- Looking for access
-- Looking for access - found
-- Looking for getpid
-- Looking for getpid - found
-- Looking for dlopen
-- Looking for dlopen - found
-- Looking for dladdr
-- Looking for dladdr - found
-- Looking for memalign
-- Looking for memalign - not found
-- Looking for posix_memalign
-- Looking for posix_memalign - found
-- Performing Test HAVE_SC_NPROCESSORS_ONLN
-- Performing Test HAVE_SC_NPROCESSORS_ONLN - Success
-- Performing Test HAVE_SC_NPROC_ONLN
-- Performing Test HAVE_SC_NPROC_ONLN - Failed
-- Performing Test HAVE_SYSCTL_HW_NCPU
-- Performing Test HAVE_SYSCTL_HW_NCPU - Success
-- Looking for ctype.h
-- Looking for ctype.h - found
-- Looking for inttypes.h
-- Looking for inttypes.h - found
-- Looking for sys/types.h
-- Looking for sys/types.h - found
-- Looking for stdint.h
-- Looking for stdint.h - found
-- Looking for stddef.h
-- Looking for stddef.h - found
-- Check size of _Bool
-- Check size of _Bool - done
-- Check size of bool
-- Check size of bool - failed
-- Check size of int
-- Check size of int - done
-- Check size of greg_t
-- Check size of greg_t - failed
-- Check size of long
-- Check size of long - done
-- Check size of long long
-- Check size of long long - done
-- Check size of long double
-- Check size of long double - done
-- Check size of mode_t
-- Check size of mode_t - done
-- Check size of off_t
-- Check size of off_t - done
-- Check size of size_t
-- Check size of size_t - done
-- Check size of wchar_t
-- Check size of wchar_t - done
-- Check size of void*
-- Check size of void* - done
-- Performing Test HAVE___BUILTIN_BSWAP16
-- Performing Test HAVE___BUILTIN_BSWAP16 - Success
-- Performing Test HAVE___BUILTIN_BSWAP32
-- Performing Test HAVE___BUILTIN_BSWAP32 - Success
-- Performing Test HAVE___BUILTIN_BSWAP64
-- Performing Test HAVE___BUILTIN_BSWAP64 - Success
-- Looking for floatingpoint.h
-- Looking for floatingpoint.h - not found
-- Looking for ieeefp.h
-- Looking for ieeefp.h - not found
-- Looking for cos
-- Looking for cos - found
-- Looking for acosh
-- Looking for acosh - found
-- Looking for asinh
-- Looking for asinh - found
-- Looking for atanh
-- Looking for atanh - found
-- Looking for copysign
-- Looking for copysign - found
-- Looking for erf
-- Looking for erf - found
-- Looking for erfc
-- Looking for erfc - found
-- Looking for hypot
-- Looking for hypot - found
-- Looking for isfinite
-- Looking for isfinite - found
-- Looking for isinf
-- Looking for isinf - found
-- Looking for isnan
-- Looking for isnan - found
-- Looking for isnand
-- Looking for isnand - not found
-- Looking for isnanf
-- Looking for isnanf - not found
-- Looking for isnormal
-- Looking for isnormal - found
-- Looking for j0
-- Looking for j0 - found
-- Looking for j1
-- Looking for j1 - found
-- Looking for jn
-- Looking for jn - found
-- Looking for lrint
-- Looking for lrint - found
-- Looking for llrint
-- Looking for llrint - found
-- Looking for log1p
-- Looking for log1p - found
-- Looking for log2
-- Looking for log2 - found
-- Looking for rint
-- Looking for rint - found
-- Looking for sincos
-- Looking for sincos - not found
-- Looking for y0
-- Looking for y0 - found
-- Looking for y1
-- Looking for y1 - found
-- Looking for yn
-- Looking for yn - found
-- Looking for acosf
-- Looking for acosf - found
-- Looking for acoshf
-- Looking for acoshf - found
-- Looking for asinf
-- Looking for asinf - found
-- Looking for asinhf
-- Looking for asinhf - found
-- Looking for atanf
-- Looking for atanf - found
-- Looking for atanhf
-- Looking for atanhf - found
-- Looking for atan2f
-- Looking for atan2f - found
-- Looking for erff
-- Looking for erff - found
-- Looking for ceilf
-- Looking for ceilf - found
-- Looking for cosf
-- Looking for cosf - found
-- Looking for coshf
-- Looking for coshf - found
-- Looking for erfcf
-- Looking for erfcf - found
-- Looking for expf
-- Looking for expf - found
-- Looking for fabsf
-- Looking for fabsf - found
-- Looking for floorf
-- Looking for floorf - found
-- Looking for fmodf
-- Looking for fmodf - found
-- Looking for hypotf
-- Looking for hypotf - found
-- Looking for logf
-- Looking for logf - found
-- Looking for log2f
-- Looking for log2f - found
-- Looking for log10f
-- Looking for log10f - found
-- Looking for log1pf
-- Looking for log1pf - found
-- Looking for lrintf
-- Looking for lrintf - found
-- Looking for llrintf
-- Looking for llrintf - found
-- Looking for powf
-- Looking for powf - found
-- Looking for rintf
-- Looking for rintf - found
-- Looking for sinf
-- Looking for sinf - found
-- Looking for sinhf
-- Looking for sinhf - found
-- Looking for sqrtf
-- Looking for sqrtf - found
-- Looking for tanf
-- Looking for tanf - found
-- Looking for tanhf
-- Looking for tanhf - found
-- Checking whether system has ANSI C header files
-- Looking for 4 include files stdlib.h, ..., float.h
-- Looking for 4 include files stdlib.h, ..., float.h - found
-- Performing Test memchrExists
-- Performing Test memchrExists - Success
-- Performing Test freeExists
-- Performing Test freeExists - Success
-- ANSI C header files - found
-- Using CFLAGS = '-std=gnu99 -flax-vector-conversions -O3 -DNDEBUG'
-- Found Sphinx: /opt/homebrew/opt/sphinx-doc/bin/sphinx-build
*
*  GMT Version:               : 6.5.0
*  System:                    : Darwin (23.2.0)
*
*  Options:
*  Found GSHHG database       : /Users/chong/Downloads/gmt-6.5.0/share/gshhg-gmt (2.3.7)
*  Found DCW-GMT database     : /Users/chong/Downloads/gmt-6.5.0/share/dcw-gmt (2.1.2)
*  Found GMT data server      : oceania
*  NetCDF library             : /opt/homebrew/Cellar/netcdf/4.9.2_1/lib/libnetcdf.dylib
*  NetCDF include dir         : /opt/homebrew/Cellar/netcdf/4.9.2_1/include
*  Curl library               : /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/lib/libcurl.tbd
*  Curl include dir           : /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/include
*  GDAL library               : /opt/homebrew/Cellar/gdal/3.8.5_2/lib/libgdal.dylib
*  GDAL include dir           : /opt/homebrew/Cellar/gdal/3.8.5_2/include
*  GEOS library               : /opt/homebrew/Cellar/geos/3.12.1/lib/libgeos_c.dylib
*  GEOS include dir           : /opt/homebrew/include
*  FFTW library               : /opt/homebrew/lib/libfftw3f.dylib
*  FFTW threads library       : /opt/homebrew/lib/libfftw3f_threads.dylib
*  FFTW include dir           : /opt/homebrew/include
*  Accelerate Framework       : /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/System/Library/Frameworks/Accelerate.framework
*  Regex support              : PCRE2 (/opt/homebrew/Cellar/pcre2/10.43/lib/libpcre2-8.dylib)
*  ZLIB library               : /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/lib/libz.tbd
*  ZLIB include dir           : /Library/Developer/CommandLineTools/SDKs/MacOSX14.2.sdk/usr/include
*  LAPACK library             : yes
*  BLAS library               : yes
*  License restriction        : no
*  Triangulation method       : Shewchuk
*  OpenMP support             : enabled
*  GLIB GTHREAD support       : enabled
*  Build generator            : Ninja
*  Build GMT core             : always [libgmt.dylib]
*  Build PSL library          : always [libpostscriptlight.dylib]
*  Build GMT supplements      : yes [supplements.so]
*  Build GMT for developers   : yes
*  Build proto supplements    : none
*  Build module links         : no
*  Found Ghostscript (gs)     : yes (10.03.0)
*  Found GraphicsMagick (gm)  : yes (1.3.43)
*  Found ffmpeg               : yes (7.0)
*  Found open                 : yes
*  Found ogr2ogr              : yes (3.8.5)
*  Found gdal_translate       : yes (3.8.5)
*
*  Locations:
*  Installing GMT in          : /opt/GMT-6.5.0
*  GMT_DATADIR                : /opt/GMT-6.5.0/share
*  GMT_DOCDIR                 : /opt/GMT-6.5.0/share/doc
*  GMT_MANDIR                 : /opt/GMT-6.5.0/share/man
-- Configuring done (10.8s)
-- Generating done (0.1s)
-- Build files have been written to: /Users/chong/Downloads/gmt-6.5.0/build

It seems the OpenMP support was enabled.
Then I did:

cmake --build .
cmake --build . --target install

Is there anything wrong?

Sorry if this is a rookie question, and many thanks!

I’m afraid it does. See this issue

I think yes. Or the llvm openmp package (not sure what it is). See this Julia thread about a similar issue.

Is conda an option for you? I’m pretty sure that the gmt package provided by conda-forge have OpenMP-enabled on macOS.

Hi @seisman ,

Many thanks! It works very well!