From 281375ed859920b549be416071ad6912488eb231 Mon Sep 17 00:00:00 2001 From: Hanno Schwalm Date: Thu, 18 Jun 2026 16:02:30 +0200 Subject: [PATCH] Some build requirement updates 1. Make OpenMP a build requirement as non-OpenMP builds - don't help for anything - add code burden that would require special testing - don't have acceptable performance External code like rawspeed and libraw are not touched. 2. With current compilers we can assume proper vectorizing support so the DT_NO_VECTORIZATION and DT_NO_SIMD_HINTS can be removed. 3. As OpenMP and SSE2 are no build options, don't show them in the log file. --- CMakeLists.txt | 20 ++++++------- DefineOptions.cmake | 1 - build.sh | 2 +- src/CMakeLists.txt | 31 +++++++++----------- src/chart/main.c | 2 -- src/common/ai/restore_rgb.c | 16 ++--------- src/common/darktable.c | 18 ------------ src/common/darktable.h | 48 ++++--------------------------- src/common/densecrf.cc | 2 -- src/common/dttypes.h | 9 +----- src/common/imagebuf.c | 36 ++++++------------------ src/common/luminance_mask.h | 12 -------- src/common/ras2vect.c | 2 -- src/config.cmake.h | 2 +- src/control/control.h | 4 +-- src/control/jobs.c | 6 +--- src/control/jobs/sidecar_jobs.c | 50 +-------------------------------- src/develop/develop.h | 2 +- src/develop/imageop.h | 4 --- src/external/CMakeLists.txt | 2 +- src/imageio/imageio_rawspeed.cc | 8 +----- src/iop/colorequal.c | 2 -- src/iop/colorin.c | 14 --------- src/iop/liquify.c | 2 -- src/iop/rasterfile.c | 2 -- src/iop/toneequal.c | 2 -- src/iop/tonemap.cc | 6 +--- src/tests/cache.c | 8 +----- tools/basecurve/CMakeLists.txt | 11 ++------ 29 files changed, 52 insertions(+), 272 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f2a23b05061..6619e8b69149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,21 +75,19 @@ else() set(RPATH_ORIGIN $ORIGIN) endif() -if (USE_OPENMP) - if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR - CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") +if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR + CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - # Clang has an option to specify the OpenMP standard to use. Specify it. - # FIXME: Implement this in FindOpenMP.cmake - set(OPENMP_VERSION_SPECIFIER "-fopenmp-version=51") + # Clang has an option to specify the OpenMP standard to use. Specify it. + # FIXME: Implement this in FindOpenMP.cmake + set(OPENMP_VERSION_SPECIFIER "-fopenmp-version=51") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENMP_VERSION_SPECIFIER}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENMP_VERSION_SPECIFIER}") - endif() - - find_package(OpenMP 4.5 REQUIRED) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENMP_VERSION_SPECIFIER}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENMP_VERSION_SPECIFIER}") endif() +find_package(OpenMP 4.5 REQUIRED) + # Check for base threading library set(CMAKE_THREAD_PREFER_PTHREAD TRUE) find_package(Threads REQUIRED) diff --git a/DefineOptions.cmake b/DefineOptions.cmake index 15fcad411853..05aff288225d 100644 --- a/DefineOptions.cmake +++ b/DefineOptions.cmake @@ -6,7 +6,6 @@ option(DONT_USE_INTERNAL_LUA "Never fall back to the intree copy of lua" ON) option(USE_KWALLET "Build kwallet password storage back-end" ON) option(USE_LIBSECRET "Build libsecret password storage back-end" ON) option(USE_UNITY "Use libunity to report progress in the launcher" OFF) -option(USE_OPENMP "Use OpenMP threading support." ON) option(USE_OPENCL "Use OpenCL support." ON) option(USE_GRAPHICSMAGICK "Use GraphicsMagick library for image import." ON) option(USE_IMAGEMAGICK "Use ImageMagick library for image import." OFF) diff --git a/build.sh b/build.sh index eb3f5fc28cda..521bfe30689b 100755 --- a/build.sh +++ b/build.sh @@ -35,7 +35,7 @@ CMAKE_OPTIONS_FROM_CMDLINE="" PRINT_HELP=0 -FEATURES="AI CAMERA COLORD GMIC GRAPHICSMAGICK IMAGEMAGICK JXL KWALLET LIBSECRET LUA MAC_INTEGRATION MAP OPENCL OPENEXR OPENMP UNITY WEBP" +FEATURES="AI CAMERA COLORD GMIC GRAPHICSMAGICK IMAGEMAGICK JXL KWALLET LIBSECRET LUA MAC_INTEGRATION MAP OPENCL OPENEXR UNITY WEBP" # prepare a lowercase version with a space before and after # it's very important for parse_feature, has no impact in for loop expansions diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40edc6397a3c..dc2cb4b8e9de 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -273,25 +273,23 @@ list(APPEND LIBS "${CMAKE_THREAD_LIBS_INIT}") # Need to explicitly link against math library. list(APPEND LIBS "-lm") -if(USE_OPENMP) - if(OpenMP_C_FLAGS) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - endif() +if(OpenMP_C_FLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") +endif() - if(OpenMP_CXX_FLAGS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - endif() +if(OpenMP_CXX_FLAGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") +endif() - if(OpenMP_C_INCLUDE_DIRS) - include_directories(${OpenMP_C_INCLUDE_DIRS}) - endif() +if(OpenMP_C_INCLUDE_DIRS) + include_directories(${OpenMP_C_INCLUDE_DIRS}) +endif() - if(OpenMP_CXX_INCLUDE_DIRS) - include_directories(${OpenMP_CXX_INCLUDE_DIRS}) - endif() +if(OpenMP_CXX_INCLUDE_DIRS) + include_directories(${OpenMP_CXX_INCLUDE_DIRS}) +endif() - list(APPEND LIBS ${OpenMP_C_LIBRARIES} ${OpenMP_CXX_LIBRARIES}) -endif(USE_OPENMP) +list(APPEND LIBS ${OpenMP_C_LIBRARIES} ${OpenMP_CXX_LIBRARIES}) if(USE_DARKTABLE_PROFILING) add_definitions(-DUSE_DARKTABLE_PROFILING) @@ -1134,9 +1132,6 @@ set(CPACK_COMPONENTS_ALL DTApplication DTDebugSymbols DTDocuments) if(USE_LIBRAW AND NOT (DONT_USE_INTERNAL_LIBRAW AND libraw_FOUND)) set(LIBRAW_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/LibRaw" CACHE STRING "Relative path to libraw directory (default=CMAKE_CURRENT_SOURCE_DIR)") - if(NOT USE_OPENMP) - set(ENABLE_OPENMP OFF CACHE BOOL "") - endif() set(ENABLE_LCMS OFF CACHE BOOL "") set(ENABLE_JASPER OFF CACHE BOOL "") diff --git a/src/chart/main.c b/src/chart/main.c index 57ece81bc526..85d45d805f8d 100644 --- a/src/chart/main.c +++ b/src/chart/main.c @@ -1910,9 +1910,7 @@ int main(int argc, char *argv[]) SetErrorMode(SEM_FAILCRITICALERRORS); #endif -#ifdef _OPENMP omp_set_num_threads(omp_get_num_procs()); -#endif int res = 1; dt_lut_t *self = (dt_lut_t *)calloc(1, sizeof(dt_lut_t)); diff --git a/src/common/ai/restore_rgb.c b/src/common/ai/restore_rgb.c index 5a0be2d98797..bba97417bd77 100644 --- a/src/common/ai/restore_rgb.c +++ b/src/common/ai/restore_rgb.c @@ -738,13 +738,7 @@ void dt_restore_apply_detail_recovery(const float *original_4ch, = dt_alloc_align_float(npix); if(!lum_residual) return; -#ifdef _OPENMP -#pragma omp parallel for simd default(none) \ - dt_omp_firstprivate(original_4ch, denoised_4ch, \ - lum_residual, npix) \ - schedule(simd:static) \ - aligned(original_4ch, denoised_4ch, lum_residual:64) -#endif + DT_OMP_FOR_SIMD(aligned(original_4ch, denoised_4ch, lum_residual:64)) for(size_t i = 0; i < npix; i++) { const size_t p = i * 4; @@ -764,13 +758,7 @@ void dt_restore_apply_detail_recovery(const float *original_4ch, dwt_denoise(lum_residual, width, height, DWT_DETAIL_BANDS, noise); -#ifdef _OPENMP -#pragma omp parallel for simd default(none) \ - dt_omp_firstprivate(denoised_4ch, lum_residual, \ - npix, alpha) \ - schedule(simd:static) \ - aligned(denoised_4ch, lum_residual:64) -#endif + DT_OMP_FOR_SIMD(aligned(denoised_4ch, lum_residual:64)) for(size_t i = 0; i < npix; i++) { const size_t p = i * 4; diff --git a/src/common/darktable.c b/src/common/darktable.c index 3a1f0e8189c9..1ba5e5725084 100644 --- a/src/common/darktable.c +++ b/src/common/darktable.c @@ -119,9 +119,7 @@ #include #endif -#ifdef _OPENMP #include -#endif #ifdef USE_LUA #include "lua/configuration.h" @@ -841,18 +839,6 @@ char *version = g_strdup_printf( " Debug -> DISABLED\n" #endif -#if defined(__SSE2__) && defined(__SSE__) - " SSE2 optimizations -> ENABLED\n" -#else - " SSE2 optimizations -> DISABLED\n" -#endif - -#ifdef _OPENMP - " OpenMP -> ENABLED\n" -#else - " OpenMP -> DISABLED\n" -#endif - #ifdef HAVE_OPENCL " OpenCL -> ENABLED\n" #else @@ -1285,12 +1271,10 @@ int dt_init(int argc, dt_print(DT_DEBUG_ALWAYS, "[dt_init --threads] requested %d ompthreads restricted to %d", desired, possible); -#ifdef _OPENMP dt_print(DT_DEBUG_ALWAYS, "[dt_init --threads] using %d threads of %d for openmp parallel sections %s", darktable.num_openmp_threads, (int)dt_get_num_procs(), omp_get_dynamic() ? "(dynamic)" : "(static)"); -#endif k++; argv[k-1] = NULL; argv[k] = NULL; @@ -1555,10 +1539,8 @@ int dt_init(int argc, darktable.gui = (dt_gui_gtk_t *)calloc(1, sizeof(dt_gui_gtk_t)); } -#ifdef _OPENMP omp_set_num_threads(darktable.num_openmp_threads); omp_set_dynamic(FALSE); -#endif #ifdef USE_LUA dt_lua_init_early(L); diff --git a/src/common/darktable.h b/src/common/darktable.h index 1979f437b403..a712406c9664 100644 --- a/src/common/darktable.h +++ b/src/common/darktable.h @@ -78,8 +78,7 @@ typedef unsigned int u_int; #include #endif -#ifdef _OPENMP -# include +#include /* See https://redmine.darktable.org/issues/12568#note-14 */ # ifdef HAVE_OMP_FIRSTPRIVATE_WITH_CONST @@ -91,15 +90,13 @@ typedef unsigned int u_int; # endif/* HAVE_OMP_FIRSTPRIVATE_WITH_CONST */ #ifndef dt_omp_sharedconst -#ifdef _OPENMP #if defined(__clang__) || __GNUC__ > 8 -# define dt_omp_sharedconst(...) shared(__VA_ARGS__) + #define dt_omp_sharedconst(...) shared(__VA_ARGS__) #else // GCC 8.4 throws string of errors "'x' is predetermined 'shared' for 'shared'" if we explicitly declare // 'const' variables as shared -# define dt_omp_sharedconst(var, ...) + #define dt_omp_sharedconst(var, ...) #endif -#endif /* _OPENMP */ #endif /* dt_omp_sharedconst */ #ifndef dt_omp_nontemporal @@ -107,25 +104,16 @@ typedef unsigned int u_int; // GCC 9 recognizes it as valid, but does not do anything with it // GCC 10+ ??? #if (__clang__+0 >= 10 || __GNUC__ >= 9) -# define dt_omp_nontemporal(...) nontemporal(__VA_ARGS__) + #define dt_omp_nontemporal(...) nontemporal(__VA_ARGS__) #else // GCC7/8 only support OpenMP 4.5, which does not have the nontemporal() directive. -# define dt_omp_nontemporal(var, ...) + #define dt_omp_nontemporal(var, ...) #endif #endif /* dt_omp_nontemporal */ #define DT_OMP_STRINGIFY(...) #__VA_ARGS__ #define DT_OMP_PRAGMA(...) _Pragma(DT_OMP_STRINGIFY(omp __VA_ARGS__)) -#else /* _OPENMP */ - -# define omp_get_max_threads() 1 -# define omp_get_thread_num() 0 - -#define DT_OMP_PRAGMA(...) - -#endif /* _OPENMP */ - #define DT_OMP_SIMD(clauses) DT_OMP_PRAGMA(simd clauses) #define DT_OMP_DECLARE_SIMD(clauses) DT_OMP_PRAGMA(declare simd clauses) #define DT_OMP_FOR(clauses) DT_OMP_PRAGMA(parallel for default(firstprivate) schedule(static) clauses) @@ -778,29 +766,17 @@ gboolean dt_supported_image(const gchar *filename); static inline size_t dt_get_num_threads() { -#ifdef _OPENMP return (size_t)CLAMP(omp_get_num_procs(), 1, darktable.num_openmp_threads); -#else - return 1; -#endif } static inline size_t dt_get_num_procs() { -#ifdef _OPENMP return (size_t)MAX(1, omp_get_num_procs()); -#else - return 1; -#endif } static inline int dt_get_thread_num() { -#ifdef _OPENMP return omp_get_thread_num(); -#else - return 0; -#endif } #define DT_INITHASH 5381 @@ -871,20 +847,6 @@ static inline float *dt_calloc_perthread_float(const size_t n, #define dt_get_bythread(buf, padsize, tnum) \ DT_IS_ALIGNED((buf) + ((padsize) * (tnum))) -// Most code in dt assumes that the compiler is capable of -// auto-vectorization. In some cases, this will yield suboptimal code -// if the compiler in fact does NOT auto-vectorize. Uncomment the -// following line for such a compiler. - -//#define DT_NO_VECTORIZATION - -// For some combinations of compiler and architecture, the compiler -// may actually emit inferior code if given a hint to vectorize a -// loop. Uncomment the following line if such a combination is the -// compilation target. - -//#define DT_NO_SIMD_HINTS - // copy the RGB channels of a pixel; includes the 'alpha' channel as // well if faster due to vectorization, but subsequent code should // ignore the value of the alpha unless explicitly set afterwards diff --git a/src/common/densecrf.cc b/src/common/densecrf.cc index f2ad66993e48..8bf305343045 100644 --- a/src/common/densecrf.cc +++ b/src/common/densecrf.cc @@ -21,9 +21,7 @@ #include #include -#ifdef _OPENMP #include -#endif #include "common/darktable.h" #include "common/densecrf.h" diff --git a/src/common/dttypes.h b/src/common/dttypes.h index f875f6a6f1ee..2371e089c065 100644 --- a/src/common/dttypes.h +++ b/src/common/dttypes.h @@ -62,14 +62,7 @@ typedef DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]; // a 3x3 matrix, padded to permit SSE instructions to be used for multiplication and addition typedef float DT_ALIGNED_ARRAY dt_colormatrix_t[4][4]; -// To be able to vectorize per-pixel loops, we need to operate on all four channels, but if the compiler does -// not auto-vectorize, doing so increases computation by 1/3 for a channel which typically is ignored anyway. -// Select the appropriate number of channels over which to loop to produce the fastest code. -#ifdef DT_NO_VECTORIZATION -#define DT_PIXEL_SIMD_CHANNELS 3 -#else #define DT_PIXEL_SIMD_CHANNELS 4 -#endif // A function to compute how many pixels each thread should process in a parallelized for loop. // For very small RoIs on a CPU with lots of threads, the last one or two hardware threads can end @@ -91,7 +84,7 @@ static inline size_t dt_cacheline_chunks(const size_t npixels, const size_t nthr // { // src[k] = dest[k] / 3.0f; // } -#if defined(_OPENMP) && defined(OPENMP_SIMD_) && !defined(DT_NO_SIMD_HINTS) +#if defined(OPENMP_SIMD_) //https://stackoverflow.com/questions/45762357/how-to-concatenate-strings-in-the-arguments-of-pragma #define _DT_Pragma_(x) _Pragma(#x) #define _DT_Pragma(x) _DT_Pragma_(x) diff --git a/src/common/imagebuf.c b/src/common/imagebuf.c index f2621b7e3829..00373be48831 100644 --- a/src/common/imagebuf.c +++ b/src/common/imagebuf.c @@ -149,7 +149,6 @@ void dt_iop_image_copy(float *const __restrict__ out, const float *const __restrict__ in, const size_t nfloats) { -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { float *const outv __attribute__((aligned(16))) = out; @@ -175,8 +174,7 @@ void dt_iop_image_copy(float *const __restrict__ out, } return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // image too small to bother parallelizing memcpy(out, in, nfloats * sizeof(float)); } @@ -245,7 +243,6 @@ void dt_iop_image_scaled_copy(float *const restrict buf, const size_t ch) { const size_t nfloats = width * height * ch; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { // we can gain a little by using a small number of threads in @@ -259,8 +256,7 @@ void dt_iop_image_scaled_copy(float *const restrict buf, buf[k] = scale * src[k]; return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // or image too small to bother parallelizing DT_OMP_SIMD(aligned(buf, src : 16)) for(size_t k = 0; k < nfloats; k++) buf[k] = scale * src[k]; @@ -273,7 +269,6 @@ void dt_iop_image_fill(float *const buf, const size_t ch) { const size_t nfloats = width * height * ch; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { const size_t nthreads = MIN(16, dt_get_num_threads()); @@ -293,8 +288,7 @@ void dt_iop_image_fill(float *const buf, } return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // image too small to bother parallelizing if(fill_value == 0.0f) { // take advantage of compiler intrinsic which is hopefully highly optimized @@ -315,7 +309,6 @@ void dt_iop_image_add_const(float *const buf, const size_t ch) { const size_t nfloats = width * height * ch; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { // we can gain a little by using a small number of threads in @@ -329,8 +322,7 @@ void dt_iop_image_add_const(float *const buf, buf[k] += add_value; return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // or image too small to bother parallelizing DT_OMP_SIMD(aligned(buf:16)) for(size_t k = 0; k < nfloats; k++) buf[k] += add_value; @@ -343,7 +335,6 @@ void dt_iop_image_add_image(float *const buf, const size_t ch) { const size_t nfloats = width * height * ch; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { // we can gain a little by using a small number of threads in @@ -357,8 +348,7 @@ void dt_iop_image_add_image(float *const buf, buf[k] += other_image[k]; return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // or image too small to bother parallelizing DT_OMP_SIMD(aligned(buf, other_image : 16)) for(size_t k = 0; k < nfloats; k++) buf[k] += other_image[k]; @@ -371,7 +361,6 @@ void dt_iop_image_sub_image(float *const buf, const size_t ch) { const size_t nfloats = width * height * ch; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { // we can gain a little by using a small number of threads in @@ -385,8 +374,7 @@ void dt_iop_image_sub_image(float *const buf, buf[k] -= other_image[k]; return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // image too small to bother parallelizing DT_OMP_SIMD(aligned(buf, other_image : 16)) for(size_t k = 0; k < nfloats; k++) buf[k] -= other_image[k]; @@ -399,7 +387,6 @@ void dt_iop_image_invert(float *const buf, const size_t ch) { const size_t nfloats = width * height * ch; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { // we can gain a little by using a small number of threads in @@ -413,8 +400,7 @@ void dt_iop_image_invert(float *const buf, buf[k] = max_value - buf[k]; return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // image too small to bother parallelizing DT_OMP_SIMD(aligned(buf:16)) for(size_t k = 0; k < nfloats; k++) buf[k] = max_value - buf[k]; @@ -427,7 +413,6 @@ void dt_iop_image_mul_const(float *const buf, const size_t ch) { const size_t nfloats = width * height * ch; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum) // is the copy big enough to outweigh threading overhead? { // we can gain a little by using a small number of threads in @@ -441,8 +426,7 @@ void dt_iop_image_mul_const(float *const buf, buf[k] *= mul_value; return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // image too small to bother parallelizing DT_OMP_SIMD(aligned(buf:16)) for(size_t k = 0; k < nfloats; k++) buf[k] *= mul_value; @@ -458,7 +442,6 @@ void dt_iop_image_linear_blend(float *const restrict buf, { const size_t nfloats = width * height * ch; const float lambda_1 = 1.0f - lambda; -#ifdef _OPENMP if(nfloats > parallel_imgop_minimum/2) // is the task big enough to outweigh threading overhead? { // we can gain a little by using a small number of threads in @@ -472,8 +455,7 @@ void dt_iop_image_linear_blend(float *const restrict buf, buf[k] = lambda*buf[k] + lambda_1*other[k]; return; } -#endif // _OPENMP - // no OpenMP, or image too small to bother parallelizing + // image too small to bother parallelizing DT_OMP_SIMD(aligned(buf:16)) for(size_t k = 0; k < nfloats; k++) buf[k] = lambda*buf[k] + lambda_1*other[k]; diff --git a/src/common/luminance_mask.h b/src/common/luminance_mask.h index 99183c4a1957..843f63f54f30 100644 --- a/src/common/luminance_mask.h +++ b/src/common/luminance_mask.h @@ -217,7 +217,6 @@ static void pixel_rgb_geomean(const float *const restrict image, // Overkill trick to explicitely unswitch loops // GCC should to it automatically with "funswitch-loops" flag, // but not sure about Clang -#ifdef _OPENMP #define LOOP(fn) \ { \ _Pragma ("omp parallel for simd default(none) schedule(static) \ @@ -229,17 +228,6 @@ static void pixel_rgb_geomean(const float *const restrict image, } \ break; \ } -#else - #define LOOP(fn) \ - { \ - for(size_t k = 0; k < num_elem; k += 4) \ - { \ - fn(in, out, k, exposure_boost, fulcrum, contrast_boost); \ - } \ - break; \ - } -#endif - __DT_CLONE_TARGETS__ static inline void luminance_mask(const float *const restrict in, diff --git a/src/common/ras2vect.c b/src/common/ras2vect.c index f24798b374f1..155a198a1c88 100644 --- a/src/common/ras2vect.c +++ b/src/common/ras2vect.c @@ -21,9 +21,7 @@ #include "develop/masks.h" -#ifdef _OPENMP #include -#endif /* Macros as in Inkscape */ #define BM_WORDBITS (8 * (int)sizeof(potrace_word)) diff --git a/src/config.cmake.h b/src/config.cmake.h index e4d757ed6e2b..01b946ea24cb 100644 --- a/src/config.cmake.h +++ b/src/config.cmake.h @@ -44,7 +44,7 @@ static const char *dt_supported_extensions[] __attribute__((unused)) = {"@DT_SUP #endif #endif -#if defined(_OPENMP) && __GNUC_PREREQ(4, 9) +#if __GNUC_PREREQ(4, 9) #define OPENMP_SIMD_ #define SIMD() simd #else diff --git a/src/control/control.h b/src/control/control.h index dd328e1b12bc..e17259206303 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2009-2025 darktable developers. + Copyright (C) 2009-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,9 +25,7 @@ #include #include -#ifdef _OPENMP #include -#endif #include "control/jobs.h" #include "control/crawler.h" diff --git a/src/control/jobs.c b/src/control/jobs.c index e88bbf8ba2e7..0ae9589565b2 100644 --- a/src/control/jobs.c +++ b/src/control/jobs.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2009-2025 darktable developers. + Copyright (C) 2009-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -505,9 +505,7 @@ gboolean dt_control_add_job(dt_job_queue_t queue_id, _dt_job_t *job) static void *_control_work_res(void *ptr) { -#ifdef _OPENMP // need to do this in every thread omp_set_num_threads(dt_get_num_threads()); -#endif worker_thread_parameters_t *params = (worker_thread_parameters_t *)ptr; dt_control_t *s = params->self; threadid = params->threadid; @@ -550,9 +548,7 @@ static void *_control_worker_kicker(void *ptr) static void *_control_work(void *ptr) { -#ifdef _OPENMP // need to do this in every thread omp_set_num_threads(dt_get_num_threads()); -#endif worker_thread_parameters_t *params = (worker_thread_parameters_t *)ptr; dt_control_t *control = params->self; threadid = params->threadid; diff --git a/src/control/jobs/sidecar_jobs.c b/src/control/jobs/sidecar_jobs.c index 866e1cf105de..89c95ad00e04 100644 --- a/src/control/jobs/sidecar_jobs.c +++ b/src/control/jobs/sidecar_jobs.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2024 darktable developers. + Copyright (C) 2024-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,30 +21,6 @@ static GSList *pending_images = NULL; static gboolean background_running = FALSE; -#ifndef _OPENMP -#include "common/dtpthread.h" -static gboolean lock_initialized = FALSE; -static dt_pthread_mutex_t pending_mutex; - -static void _lock_pending_queue() -{ - if(!lock_initialized) - { - dt_pthread_mutex_init(&pending_mutex, NULL); - lock_initialized = TRUE; - } - dt_pthread_mutex_lock(&pending_mutex); -} - -static void _unlock_pending_queue() -{ - if(lock_initialized) - { - dt_pthread_mutex_unlock(&pending_mutex); - } -} -#endif /* !_OPENMP */ - static int32_t _control_write_sidecars_job_run(dt_job_t *job) { GSList *imgs = NULL; @@ -60,16 +36,8 @@ static int32_t _control_write_sidecars_job_run(dt_job_t *job) if(curr_fetch > prev_fetch + 0.25) { prev_fetch = curr_fetch; -#ifdef _OPENMP #pragma omp atomic capture { new_imgs = pending_images; pending_images = NULL ; } -#else - // don't have atomics, so use locks instead - _lock_pending_queue(); - new_imgs = pending_images; - pending_images = NULL; - _unlock_pending_queue(); -#endif if(new_imgs) { // add the new images to the queue being processed if they are not already on the queue @@ -116,16 +84,8 @@ void dt_sidecar_synch_enqueue(dt_imgid_t imgid) if(background_running) { GSList *img = g_slist_prepend(NULL,GINT_TO_POINTER(imgid)); -#ifdef _OPENMP #pragma omp atomic capture { img->next = pending_images; pending_images = img; } -#else - // don't have atomics, so use locks instead - _lock_pending_queue(); - img->next = pending_images; - pending_images = img; - _unlock_pending_queue(); -#endif } else { @@ -153,16 +113,8 @@ void dt_sidecar_synch_enqueue_list(const GList *imgs) new_imgs = g_slist_prepend(new_imgs,ilist->data); } GSList *last = g_slist_last(new_imgs); -#ifdef _OPENMP #pragma omp atomic capture { last->next = pending_images; pending_images = new_imgs; } -#else - // don't have atomics, so use locks instead - _lock_pending_queue(); - last->next = pending_images; - pending_images = new_imgs; - _unlock_pending_queue(); -#endif } void dt_control_sidecar_synch_start() diff --git a/src/develop/develop.h b/src/develop/develop.h index 99f5d610f634..38377d11a047 100644 --- a/src/develop/develop.h +++ b/src/develop/develop.h @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2009-2025 darktable developers. + Copyright (C) 2009-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/develop/imageop.h b/src/develop/imageop.h index d8408ca8767c..f3b5aaa13932 100644 --- a/src/develop/imageop.h +++ b/src/develop/imageop.h @@ -650,11 +650,7 @@ static inline void dt_sfence() // parallelization, we should play it safe and emit a memory fence. // This function should be used right after a parallelized for loop, // where it will produce a barrier only if needed. -#ifdef _OPENMP #define dt_omploop_sfence() -#else -#define dt_omploop_sfence() dt_sfence() -#endif #ifdef __SSE2__ static inline unsigned int dt_mm_enable_flush_zero() diff --git a/src/external/CMakeLists.txt b/src/external/CMakeLists.txt index e14c9891b9ea..c83d6dfc30d6 100644 --- a/src/external/CMakeLists.txt +++ b/src/external/CMakeLists.txt @@ -32,7 +32,7 @@ set(BUILD_BENCHMARKING_SAVE "${BUILD_BENCHMARKING}") set(BUILD_TESTING OFF CACHE BOOL "" FORCE) set(BUILD_BENCHMARKING OFF CACHE BOOL "" FORCE) set(BUILD_FUZZERS OFF CACHE BOOL "" FORCE) -set(WITH_OPENMP ${USE_OPENMP} CACHE BOOL "" FORCE) +set(WITH_OPENMP ON) set(RAWSPEED_PATH "${CMAKE_CURRENT_SOURCE_DIR}/rawspeed") set(RAWSPEED_BINARY_PREFIX "darktable") diff --git a/src/imageio/imageio_rawspeed.cc b/src/imageio/imageio_rawspeed.cc index 7f7dabe7ff8e..a317e007a759 100644 --- a/src/imageio/imageio_rawspeed.cc +++ b/src/imageio/imageio_rawspeed.cc @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2010-2025 darktable developers. + Copyright (C) 2010-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,9 +16,7 @@ along with darktable. If not, see . */ -#ifdef _OPENMP #include -#endif #include "RawSpeed-API.h" #include "io/FileIOException.h" @@ -46,11 +44,7 @@ // define this function, it is only declared in rawspeed: int rawspeed_get_number_of_processor_cores() { -#ifdef _OPENMP return omp_get_num_procs(); -#else - return 1; -#endif } using namespace rawspeed; diff --git a/src/iop/colorequal.c b/src/iop/colorequal.c index dfadc4c5b342..fe017e207ffa 100644 --- a/src/iop/colorequal.c +++ b/src/iop/colorequal.c @@ -84,9 +84,7 @@ None;midi:CC24=iop/colorequal/brightness/magenta #include "iop/choleski.h" #include "common/colorspaces_inline_conversions.h" -#ifdef _OPENMP #include -#endif #define NODES 8 #define SATSIZE 4096 diff --git a/src/iop/colorin.c b/src/iop/colorin.c index b1214f67910c..f08c5fcdf06c 100644 --- a/src/iop/colorin.c +++ b/src/iop/colorin.c @@ -915,7 +915,6 @@ static void process_cmatrix_fastpath(dt_iop_module_t *self, // figure out the number of pixels each thread needs to process, // rounded up to a multiple of the CPU's cache line size -#ifdef _OPENMP const size_t nthreads = dt_get_num_threads(); const size_t chunksize = dt_cacheline_chunks(npixels, nthreads); DT_OMP_FOR() @@ -930,12 +929,6 @@ static void process_cmatrix_fastpath(dt_iop_module_t *self, else _cmatrix_fastpath_simple(out + 4*start, in + 4*start, end-start, d->cmatrix, corr); } -#else // no OpenMP - if(clipping) - _cmatrix_fastpath_clipping(out, in, npixels, d->nmatrix, d->lmatrix, corr); - else - _cmatrix_fastpath_simple(out, in, npixels, d->cmatrix, corr); -#endif // ensure that all nontemporal writes have been flushed to RAM before we return dt_omploop_sfence(); } @@ -1041,7 +1034,6 @@ static void process_cmatrix_proper(dt_iop_module_t *self, // figure out the number of pixels each thread needs to process, // rounded up to a multiple of the CPU's cache line size -#ifdef _OPENMP const size_t nthreads = dt_get_num_threads(); const size_t chunksize = dt_cacheline_chunks(npixels, nthreads); DT_OMP_FOR() @@ -1056,12 +1048,6 @@ static void process_cmatrix_proper(dt_iop_module_t *self, else _cmatrix_proper_simple(out + 4*start, in + 4*start, end-start, d, d->cmatrix, corr); } -#else - if(clipping) - _cmatrix_proper_clipping(out, in, npixels, d,d->nmatrix, d->lmatrix, corr); - else - _cmatrix_proper_simple(out, in, npixels, d, d->cmatrix, corr); -#endif // ensure that all nontemporal writes have been flushed to RAM before we return dt_omploop_sfence(); } diff --git a/src/iop/liquify.c b/src/iop/liquify.c index 6b470f3bbde9..8ad5f15f9bd3 100644 --- a/src/iop/liquify.c +++ b/src/iop/liquify.c @@ -35,9 +35,7 @@ #include #include -#ifdef _OPENMP #include -#endif // this is the version of the modules parameters, and includes version // information about compile-time dt diff --git a/src/iop/rasterfile.c b/src/iop/rasterfile.c index e2a77257397c..d2c8d2b8801d 100644 --- a/src/iop/rasterfile.c +++ b/src/iop/rasterfile.c @@ -47,9 +47,7 @@ #include "win/scandir.h" #endif -#ifdef _OPENMP #include -#endif #define SET_THRESHOLD 0.6f diff --git a/src/iop/toneequal.c b/src/iop/toneequal.c index 7b6440c4d88e..5528b1f2ef0e 100644 --- a/src/iop/toneequal.c +++ b/src/iop/toneequal.c @@ -119,9 +119,7 @@ #include "iop/choleski.h" #include "common/iop_group.h" -#ifdef _OPENMP #include -#endif DT_MODULE_INTROSPECTION(2, dt_iop_toneequalizer_params_t) diff --git a/src/iop/tonemap.cc b/src/iop/tonemap.cc index 52bdb72d4dbc..1b444b49cf3b 100644 --- a/src/iop/tonemap.cc +++ b/src/iop/tonemap.cc @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2010-2021 darktable developers. + Copyright (C) 2010-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -116,9 +116,7 @@ void process(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *c // Build I=log(L) // and splat into the lattice -#ifdef _OPENMP #pragma omp parallel for shared(lattice) -#endif for(int j = 0; j < height; j++) { size_t index = (size_t)j * width; @@ -161,9 +159,7 @@ void process(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, const void *c // const float contr = 1. / data->contrast; -#ifdef _OPENMP #pragma omp parallel for -#endif for(int j = 0; j < height; j++) { size_t index = (size_t)j * width; diff --git a/src/tests/cache.c b/src/tests/cache.c index dcdf85c6db86..31eb51e58779 100644 --- a/src/tests/cache.c +++ b/src/tests/cache.c @@ -1,6 +1,6 @@ /* This file is part of darktable, - Copyright (C) 2011-2023 darktable developers. + Copyright (C) 2011-2026 darktable developers. darktable is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,9 +29,7 @@ #include #include #include -#ifdef _OPENMP #include -#endif int32_t alloc_dummy(void *data, const uint32_t key, int32_t *cost, void **buf) { @@ -49,9 +47,7 @@ int main(int argc, char *arg[]) dt_cache_init(&cache, 110000, 16, 64, 100); dt_cache_set_allocate_callback(&cache, alloc_dummy, NULL); -#ifdef _OPENMP #pragma omp parallel for default(none) schedule(guided) shared(cache, stderr) num_threads(16) -#endif for(int k = 0; k < 100000; k++) { void *data = (void *)(long int)k; @@ -92,9 +88,7 @@ int main(int argc, char *arg[]) dt_cache_init(&cache2, 1, 1, 64, 2); dt_cache_set_allocate_callback(&cache2, alloc_dummy, NULL); -#ifdef _OPENMP #pragma omp parallel for default(none) schedule(guided) shared(cache2, stderr) num_threads(16) -#endif for(int k = 0; k < 100000; k++) { void *data = (void *)(long int)k; diff --git a/tools/basecurve/CMakeLists.txt b/tools/basecurve/CMakeLists.txt index 3e7045e4f630..5865c18d8b1d 100644 --- a/tools/basecurve/CMakeLists.txt +++ b/tools/basecurve/CMakeLists.txt @@ -1,10 +1,6 @@ # Only build on real *nix system or MSYS2 installation if ((NOT WIN32) OR BUILD_MSYS2_INSTALL) - if (USE_OPENMP) - find_package(OpenMP) - else() - set(OPENMP_FOUND FALSE) - endif() + find_package(OpenMP) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules") find_library(M_LIBRARY m) @@ -16,12 +12,11 @@ if ((NOT WIN32) OR BUILD_MSYS2_INSTALL) endif() add_executable(darktable-curve-tool darktable-curve-tool.c exif-wrapper.cpp) - if (OPENMP_FOUND) - set_target_properties(darktable-curve-tool PROPERTIES COMPILE_FLAGS ${OpenMP_CXX_FLAGS}) + set_target_properties(darktable-curve-tool PROPERTIES COMPILE_FLAGS ${OpenMP_CXX_FLAGS}) if(OpenMP_CXX_INCLUDE_DIRS) include_directories(${OpenMP_CXX_INCLUDE_DIRS}) endif() - endif() + target_link_libraries(darktable-curve-tool ${Exiv2_LIBRARY} ${OpenMP_CXX_LIBRARIES} m) configure_file(README.cmake.md README.md)