From ef015a68303cb5b7700e852015db91a760daa1e0 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Sat, 10 Jun 2023 20:35:59 +0300 Subject: [PATCH 1/2] blas_thread_shutdown: release OpenMP resources too OpenMP 5.0 introduced the function omp_pause_resource_all that instructs the runtime to "relinquish resources used by OpenMP on all devices". In practice, these resources include the locks that would otherwise trip up the runtime after a fork(). Releasing these resources in a function called by pthread_atfork() makes it possible for the child process to continue functioning after the runtime automatically re-acquires its resources. Thread safety: blas_thread_shutdown doesn't check whether there are other BLAS operations running in parallel, so this isn't any less safe than before with respect to OpenBLAS function calls. On the other hand, if there are other OpenMP operations in progress, asking the runtime to pause may result in unspecified behaviour. A hard pause is allowed to deallocate threadprivate variables too. --- driver/others/blas_server_omp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/driver/others/blas_server_omp.c b/driver/others/blas_server_omp.c index 2e0c0f38c..08bf2170f 100644 --- a/driver/others/blas_server_omp.c +++ b/driver/others/blas_server_omp.c @@ -48,6 +48,7 @@ #else +#include #ifndef likely #ifdef __GNUC__ #define likely(x) __builtin_expect(!!(x), 1) @@ -147,6 +148,9 @@ int BLASFUNC(blas_thread_shutdown)(void){ } } } +#if defined(_OPENMP) && _OPENMP >= 201811 + omp_pause_resource_all(omp_pause_hard); +#endif return 0; } From 645eabe67f1fc01da855647f63e1b1576b495bb3 Mon Sep 17 00:00:00 2001 From: Ivan K Date: Sat, 10 Jun 2023 21:20:58 +0300 Subject: [PATCH 2/2] utest: test fork safety on OpenMP >= 5 In addition to testing fork safety on non-OpenMP builds, test it on OpenMP >= 5.0, where we get the ability to release the locks at fork() time. --- utest/Makefile | 5 +---- utest/test_fork.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/utest/Makefile b/utest/Makefile index f99035440..eecd9d199 100644 --- a/utest/Makefile +++ b/utest/Makefile @@ -26,10 +26,7 @@ endif #this does not work with OpenMP nor with native Windows or Android threads # FIXME TBD if this works on OSX, SunOS, POWER and zarch ifeq ($(OSNAME), $(filter $(OSNAME),Linux CYGWIN_NT)) -ifneq ($(USE_OPENMP), 1) -OBJS += test_fork.o -endif -OBJS += test_post_fork.o +OBJS += test_fork.o test_post_fork.o endif ifeq ($(C_COMPILER), PGI) diff --git a/utest/test_fork.c b/utest/test_fork.c index bd531e7fb..b1cd380e6 100644 --- a/utest/test_fork.c +++ b/utest/test_fork.c @@ -64,7 +64,7 @@ static void check_dgemm(double *a, double *b, double *result, double *expected, CTEST(fork, safety) { -#ifndef BUILD_DOUBLE +#if !defined(BUILD_DOUBLE) || (defined(_OPENMP) && _OPENMP < 201811) exit(0); #else blasint n = 1000;