public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
From: "johnnybit at gmail dot com" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug middle-end/101262] GCC11 OpenMP optimization causes sigsegv on aligned constant array in darktable
Date: Tue, 29 Jun 2021 19:06:32 +0000	[thread overview]
Message-ID: <bug-101262-4-M4EiBZ3mN4@http.gcc.gnu.org/bugzilla/> (raw)
In-Reply-To: <bug-101262-4@http.gcc.gnu.org/bugzilla/>

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101262

--- Comment #2 from Hubert Kowalski <johnnybit at gmail dot com> ---
I've tried producing a minimum reproducer in form of code below, however I run
on gcc 10.3. And it depends on optimization type.

According to user reports - it's enough to compile darktable using GCC 11 with
RelWithDebInfo target (it applies -O2). Builds with Release target (-O3) are
apparently "fine"

(below code theoretically reproduces issue, but afaik it might not reliably
reproduce the problem)

#include <math.h>
#include <stdlib.h>
#include <omp.h>

#if defined(__GNUC__)
#pragma GCC optimize ("unroll-loops", "tree-loop-if-convert", \
                      "tree-loop-distribution", "no-strict-aliasing", \
                      "loop-interchange", "loop-nest-optimize", "tree-loop-im",
\
                      "unswitch-loops", "tree-loop-ivcanon",
"ira-loop-pressure", \
                      "split-ivs-in-unroller",
"variable-expansion-in-unroller", \
                      "split-loops", "ivopts", "predictive-commoning",\
                      "tree-loop-linear", "loop-block", "loop-strip-mine", \
                      "finite-math-only", "fp-contract=fast", "fast-math")
#endif

#define dt_omp_firstprivate(...) firstprivate(__VA_ARGS__)
#define __DT_CLONE_TARGETS__ __attribute__((target_clones("default", "sse2",
"sse3", "sse4.1", "sse4.2", "popcnt", "avx", "avx2", "avx512f", "fma4")))
#define DT_ALIGNED_ARRAY __attribute__((aligned(64)))
#define PIXEL_CHAN 8
#define UI_SAMPLES 256

// radial distances used for pixel ops
static const float centers_ops[PIXEL_CHAN] DT_ALIGNED_ARRAY = {-56.0f / 7.0f,
// = -8.0f
                                                               -48.0f / 7.0f,
                                                               -40.0f / 7.0f,
                                                               -32.0f / 7.0f,
                                                               -24.0f / 7.0f,
                                                               -16.0f / 7.0f,
                                                                -8.0f / 7.0f,
                                                                 0.0f / 7.0f};

typedef struct dt_iop_toneequalizer_gui_data_t
{
  // Mem arrays 64-bits aligned - contiguous memory
  float factors[PIXEL_CHAN] DT_ALIGNED_ARRAY;
  float gui_lut[UI_SAMPLES] DT_ALIGNED_ARRAY; // LUT for the UI graph
  float sigma;
} dt_iop_toneequalizer_gui_data_t;

#pragma omp declare simd
__DT_CLONE_TARGETS__
static inline float fast_clamp(const float value, const float bottom, const
float top)
{
  // vectorizable clamping between bottom and top values
  return fmaxf(fminf(value, top), bottom);
}

#pragma omp declare simd
__DT_CLONE_TARGETS__
static float gaussian_denom(const float sigma)
{
  // Gaussian function denominator such that y = exp(- radius^2 / denominator)
  // this is the constant factor of the exponential, so we don't need to
recompute it
  // for every single pixel
  return 2.0f * sigma * sigma;
}

#pragma omp declare simd
__DT_CLONE_TARGETS__
static float gaussian_func(const float radius, const float denominator)
{
  // Gaussian function without normalization
  // this is the variable part of the exponential
  // the denominator should be evaluated with `gaussian_denom`
  // ahead of the array loop for optimal performance
  return expf(- radius * radius / denominator);
}

__DT_CLONE_TARGETS__
static inline float pixel_correction(const float exposure,
                                     const float *const restrict factors,
                                     const float sigma)
{
  // build the correction for the current pixel
  // as the sum of the contribution of each luminance channel
  float result = 0.0f;
  const float gauss_denom = gaussian_denom(sigma);
  const float expo = fast_clamp(exposure, -8.0f, 0.0f);

#pragma omp simd aligned(centers_ops, factors:64) safelen(PIXEL_CHAN)
reduction(+:result)
  for(int i = 0; i < PIXEL_CHAN; ++i)
    result += gaussian_func(expo - centers_ops[i], gauss_denom) * factors[i];

  return fast_clamp(result, 0.25f, 4.0f);
}

__DT_CLONE_TARGETS__
static inline void compute_lut_correction(struct
dt_iop_toneequalizer_gui_data_t *g,
                                          const float offset,
                                          const float scaling)
{
  // Compute the LUT of the exposure corrections in EV,
  // offset and scale it for display in GUI widget graph

  float *const restrict LUT = g->gui_lut;
  const float *const restrict factors = g->factors;
  const float sigma = g->sigma;

#pragma omp parallel for simd schedule(static) default(none) \
  dt_omp_firstprivate(factors, sigma, offset, scaling, LUT) \
  aligned(LUT, factors:64)
  for(int k = 0; k < UI_SAMPLES; k++)
  {
    // build the inset graph curve LUT
    // the x range is [-14;+2] EV
    const float x = (8.0f * (((float)k) / ((float)(UI_SAMPLES - 1)))) - 8.0f;
    LUT[k] = offset - log2f(pixel_correction(x, factors, sigma)) / scaling;
  }
}

int main() {
    dt_iop_toneequalizer_gui_data_t *g = calloc(1,
sizeof(dt_iop_toneequalizer_gui_data_t));
    compute_lut_correction(g, 0.5f, 4.0f);
}

  parent reply	other threads:[~2021-06-29 19:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-29 17:21 [Bug c/101262] New: " johnnybit at gmail dot com
2021-06-29 17:54 ` [Bug middle-end/101262] " jakub at gcc dot gnu.org
2021-06-29 19:06 ` johnnybit at gmail dot com [this message]
2021-06-29 22:45 ` jakub at gcc dot gnu.org
2021-06-30  4:22 ` johnnybit at gmail dot com
2021-06-30  4:42 ` marxin at gcc dot gnu.org
2021-06-30  6:36 ` [Bug middle-end/101262] [11/12 Regression] " rguenth at gcc dot gnu.org
2021-07-28  7:07 ` rguenth at gcc dot gnu.org
2022-04-21  7:49 ` rguenth at gcc dot gnu.org
2023-05-29 10:05 ` [Bug middle-end/101262] [11/12/13/14 " jakub at gcc dot gnu.org

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-101262-4-M4EiBZ3mN4@http.gcc.gnu.org/bugzilla/ \
    --to=gcc-bugzilla@gcc.gnu.org \
    --cc=gcc-bugs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).