Skip to content

raw denoise: X-Trans export changes with the number of threads #22456

Description

@kofa73

Is there an existing issue for this?

  • I checked and did not find my issue in the already reported ones

Describe the bug

With raw denoise enabled on an X-Trans image, the export depends on the number of threads (-t, or the CPU count by default). With the history of integration test 0068, a full-size export with -t 5 differs from one with -t 1 in 6486 pixels, by up to 5/255, in a band across the full width around row 1672. So the same image and history export differently on machines with different CPU counts.

Steps to reproduce

  1. In a darktable checkout with the src/tests/integration submodule, run cd src/tests/integration.
  2. Run OMP_NUM_THREADS=1 darktable-cli images/mire1-xtrans.raf 0068-rawdenoise-xtrans/rawdenoise-xtrans.xmp /tmp/t1.png --core --disable-opencl -t 1 --configdir /tmp/dt-t1.
  3. Run OMP_NUM_THREADS=5 darktable-cli images/mire1-xtrans.raf 0068-rawdenoise-xtrans/rawdenoise-xtrans.xmp /tmp/t5.png --core --disable-opencl -t 5 --configdir /tmp/dt-t5.
  4. Run compare -metric AE /tmp/t1.png /tmp/t5.png /tmp/diff.png. It prints 6486, and /tmp/diff.png shows a band of changed pixels across the image around row 1672.

Expected behavior

The export is the same for every thread count.

Logfile | Screenshot | Screencast

$ compare -metric AE /tmp/t1.png /tmp/t5.png /tmp/diff.png
6486 (0.000248426)

difference image from step 4:

Image

Commit

Not bisected. The chunked plane extraction came with c61568e (#7202, 2020). Its description says it reduced the differences between thread counts but did not remove them all.

Where did you obtain darktable from?

self compiled

darktable version

5.7.0+1090~gd060937f63-dirty

What OS are you using?

Linux

What is the version of your OS?

Ubuntu 26.04.1 LTS

Describe your system

AMD Ryzen 5 5600X (6 cores, 12 threads), 62 GiB RAM, glibc 2.43, GTK 3.24.52, GraphicsMagick 1.3.46. Only darktable-cli was used.

Are you using OpenCL GPU in darktable?

No

If yes, what is the GPU card and driver?

No response

Please provide additional context if applicable. You can attach files too, but might need to rename to .txt or .zip

  • Other versions: not tried. The runs used master fa3fc72294. The printed version belongs to the build tree, which is one commit later and differs from master only in src/common/darktable.c. The runs linked that file from master.
  • RAW or JPEG: X-Trans raw only. Bayer raws use another code path.
  • Fresh edit: the history is the XMP of integration test 0068.
  • Empty config dir: yes, a new --configdir for every run.
  • Lua: none.
  • OMP_NUM_THREADS matches -t because on master, darktable-cli crashes on X-Trans images with -t below the CPU count (darktable-cli: -t N below the CPU count corrupts the heap #22436, fix in common: restore OpenMP thread limit after GraphicsMagick init #22438).
  • Seen in every run. Repeated -t 5 exports are identical to each other. The integration runner sets OMP_THREAD_LIMIT=4 next to -t 4 so that this test matches its reference (see integration tests for X-Trans demosaic #7087).

Cause (confirmed). wavelet_denoise_xtrans() splits the construction of each color plane into dt_get_num_threads() row chunks (src/iop/rawdenoise.c:338-341). The last row of a chunk copies green values down into the first row of the next chunk (:369). When the chunks run concurrently, that copy lands after the next chunk wrote the row, and the repair block restores a green only if its right neighbor is not green (:429). Where a chunk boundary splits a 2×2 green block, one green in three along the boundary row keeps the value of the green above it. Confirmed two ways. The band disappears when the chunks run one after another (OMP_THREAD_LIMIT=1 with -t 5). Building the plane in a single chunk (nthreads = 1 at :338) makes the -t 4, -t 5 and -t 12 exports identical to -t 1, at a cost of about 0.1 s per 26-megapixel export at 12 threads.

A second defect at the same boundaries leaves one plane position next to the image edge unwritten, see #22457.

Found and reproduced by an AI agent (Claude). Not yet reproduced by a human.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions