Skip to content

BUG: Read the shared face-count map without inserting in Compute Triangle Face Ids - #1858

Merged
imikejackson merged 1 commit into
BlueQuartzSoftware:developfrom
joeykleingers:bug/shared-feature-face-concurrent-map
Oct 30, 2026
Merged

imikejackson merged 1 commit into
BlueQuartzSoftware:developfrom
joeykleingers:bug/shared-feature-face-concurrent-map

Conversation

@joeykleingers

@joeykleingers joeykleingers commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Compute Triangle Face Ids fills the feature face labels and triangle counts in a parallel loop. Every worker read the shared face-count map with std::map::operator[]. Row 0 is the reserved (0,0) boundary. When no triangle uses that pair, the row 0 lookup inserted key 0 and could rebalance the tree while other workers searched it. That is a data race and undefined behavior on every platform. The workers now only read the map, and the filter output does not change. 2 files changed, +112 / −4 lines.

1. Read-only map lookup in the parallel loop

  • src/Plugins/SimplnxCore/src/SimplnxCore/Filters/Algorithms/SharedFeatureFace.cpp — SharedFeatureFaceImpl

SharedFeatureFaceImpl takes the face-count map by const reference and looks each count up with find(). A missing entry gives a count of 0, the same value the old insert produced. The map is built serially before the parallel loop starts and is not changed after that.

2. Regression tests

  • src/Plugins/SimplnxCore/test/SharedFeatureFaceTest.cpp — two new test cases and a shared helper, ExecuteAndCheckLabelPairs

SharedFeatureFace: Missing zero pair rotation race uses first-seen pairs (0,2) and (0,1), so the map holds keys 2 and 1 and an insert of key 0 would rotate the tree at its root. It runs the filter 300 times and checks every ID, label and count, plus the tuple shapes of the outputs. It takes about 0.04 s in a Release build.

SharedFeatureFace: Real zero pair counts uses a real (0,0) pair and checks that the reserved row and the real row both report its count of 2.

A plain test cannot fail on a data race reliably, so the race was checked with ThreadSanitizer on macOS arm64 (simplnx instrumented, TBB not instrumented). With the old lookup, the first test reported a write to the map from inside the parallel loop in every run (15 of 15 runs across two versions of the test). With the fix, no run reported one (15 runs). The other ThreadSanitizer warnings come from TBB's own scheduler, which is not instrumented, and appear with and without the fix. MSVC has no ThreadSanitizer, so on Windows the check is that the tests pass.

Test plan

  • SimplnxCore::SharedFeatureFace* tests pass on macOS arm64 Release (3/3)
  • ThreadSanitizer reports no write to the face-count map from the parallel loop with the fix, and reports one in every run without it
  • CI passes on Windows, Linux and macOS

Related Issue

Closes #1772

@imikejackson
imikejackson self-requested a review October 29, 2026 21:37
@imikejackson
imikejackson enabled auto-merge (squash) October 29, 2026 21:37
@joeykleingers
joeykleingers force-pushed the bug/shared-feature-face-concurrent-map branch from 782d573 to 95d2c69 Compare October 29, 2026 21:54
…ngle Face Ids

The parallel loop that fills the feature face labels and triangle counts
called std::map::operator[] on a map that every worker shares. Row 0 is the
reserved (0,0) boundary. When no triangle uses that pair, the row 0 lookup
inserted key 0 and could rebalance the tree while other workers searched it.
That is a data race.

The workers now take the map by const reference and look counts up with
find(). A missing entry gives a count of 0, the same value the insert
produced, so the output does not change.

Two tests cover the change. The first builds the map from keys 2 and 1, so
that inserting key 0 would rotate the tree, and runs the filter 300 times.
Under ThreadSanitizer the old code reported a write to the map from inside
the parallel loop in every run; the fixed code reported none. The second
uses a real (0,0) pair and checks that the reserved row keeps its count.

Fixes BlueQuartzSoftware#1772

Signed-off-by: Joey Kleingers <joey.kleingers@bluequartz.net>
@imikejackson
imikejackson force-pushed the bug/shared-feature-face-concurrent-map branch from 95d2c69 to 91d2f8c Compare October 30, 2026 13:04
@imikejackson
imikejackson merged commit 2a7fab7 into BlueQuartzSoftware:develop Oct 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Avoid concurrent map insertion in Compute Triangle Face Ids

2 participants