From 2bf7fac17675633b2ec99997f9731bbe91fbbd3b Mon Sep 17 00:00:00 2001 From: Jorn Visser Date: Wed, 20 Nov 2024 10:23:57 +0100 Subject: [PATCH] Creator: Ensure OpenMP runtime is initialized as soon as possible This is to make sure duplicate libomp/libiomp5 runtime conflicts are detected as soon as a second runtime is initialized. Otherwise, it may not crash until Blender's OpenMP runtime is initialized by a feature that uses it, making such issues possibly go unnoticed. Such a conflict can happen when an add-on has a native module that uses OpenMP and links to a different libomp runtime, as was the case in #125255. Currently Blender only ships with libomp on MacOS. --- When libomp detects such an issue it should abort and print the following message: ``` OMP: Error #15: Initializing libomp.a, but found libomp.dylib already initialized. OMP: Hint This means that multiple copies of the OpenMP runtime have been linked into the program. That is dangerous, since it can degrade performance or cause incorrect results. The best thing to do is to ensure that only a single OpenMP runtime is linked into the process, e.g. by avoiding static linking of the OpenMP runtime in any library. As an unsafe, unsupported, undocumented workaround you can set the environment variable KMP_DUPLICATE_LIB_OK=TRUE to allow the program to continue to execute, but that may cause crashes or silently produce incorrect results. For more information, please see http://openmp.llvm.org/ ``` Pull Request: https://projects.blender.org/blender/blender/pulls/130407 --- source/creator/CMakeLists.txt | 6 ++++++ source/creator/creator.cc | 17 ++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 91d802cbe73..b3a7324051f 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -40,6 +40,12 @@ if(WITH_TBB) list(INSERT LIB 0 bf_blenkernel) endif() +if(WITH_OPENMP AND WITH_OPENMP_STATIC) + list(APPEND LIB + ${OpenMP_LIBRARIES} + ) +endif() + if(WIN32) list(APPEND INC ../../intern/utfconv) endif() diff --git a/source/creator/creator.cc b/source/creator/creator.cc index 310e2cbfc48..2366060622e 100644 --- a/source/creator/creator.cc +++ b/source/creator/creator.cc @@ -82,6 +82,10 @@ # include #endif +#ifdef _OPENMP +# include +#endif + #ifdef WITH_BINRELOC # include "binreloc.h" #endif @@ -300,12 +304,19 @@ int main(int argc, setvbuf(stdout, nullptr, _IONBF, 0); #endif -#ifdef WIN32 -/* We delay loading of OPENMP so we can set the policy here. */ -# if defined(_MSC_VER) +#ifdef _OPENMP +# if defined(WIN32) && defined(_MSC_VER) + /* We delay loading of OPENMP so we can set the policy here. */ _putenv_s("OMP_WAIT_POLICY", "PASSIVE"); # endif + /* Ensure the OpenMP runtime is initialized as soon as possible to make sure duplicate + * libomp/libiomp5 runtime conflicts are detected as soon as a second runtime is initialized. + * Initialization must be done after setting any relevant environment variables, but before + * installing signal handlers. */ + omp_get_max_threads(); +#endif +#ifdef WIN32 # ifdef USE_WIN32_UNICODE_ARGS /* Win32 Unicode Arguments. */ {