Closed seanm closed 2 days ago
Juts wondering... Could it be that multiple threads share one and the same region as outputRegionForThread
? Or at least, could there be any overlap between the output regions of threads?
Otherwise, could it possibly be that input and output image may be one and the same image?
Honestly, I'm clueless π€·
Honestly, I'm clueless π€·
I see two potential issues. It looks like the neighborhood iterators may go outside the outputRegionForThread.
Edited for sanity.
Thanks @blowekamp What do you think about the use of a "face list" in this case? As in: https://github.com/InsightSoftwareConsortium/ITK/blob/18d683ec792bfa7b7a950f781cf9836a5ef64a4d/Modules/Filtering/BinaryMathematicalMorphology/include/itkObjectMorphologyImageFilter.hxx#L140-L142
I think such a face list is meant to allow dealing with the "inner face" (center sub-region) differently than with the boundary faces. Typically, the boundary faces might need a different way to extrapolate or estimate outer pixel values. Right?
However, it looks like ObjectMorphologyImageFilter
treats the boundary faces just like the inner face. It just processed all faces, when it does for (const auto & face : faceList)
. (The first element of faceList
is the inner face, the other elements are the boundary faces.) Is that OK?
I'll look into this today, after I address a build error I encountered.
However, it looks like
ObjectMorphologyImageFilter
treats the boundary faces just like the inner face. It just processed all faces, when it doesfor (const auto & face : faceList)
. (The first element offaceList
is the inner face, the other elements are the boundary faces.) Is that OK?
Elaborating on my question regarding the use of faces: Originally (in 2002), ObjectMorphologyImageFilter
did treat the first face (the inner sub-region) different than the other faces (the boundary sub-regions).
For the other faces (the boundary sub-regions), a different boundary condition was used:
That makes totally sense to me. However, from 43436bf8ab71e250a624f0225e37a6e19c646576 (2023), all faces were treated equally. I think that's a mistake. The center sub-region (the first face) is special, so it deserves special treatment π
Feel free to turn that into a PR π
After this one is finished π
That makes totally sense to me. However, from 43436bf (2023), all faces were treated equally. I think that's a mistake. The center sub-region (the first face) is special, so it deserves special treatment π
The correctness is a separate issue from the race condition.
Perhaps the real issue with identifying what the correct behavior it that the regression tests only print pixel to the std output: https://github.com/InsightSoftwareConsortium/ITK/blob/11ea27f311370ca996a1f29b35bc954bcfe2987e/Modules/Filtering/BinaryMathematicalMorphology/test/itkErodeObjectMorphologyImageFilterTest.cxx#L108-L117
So we really don't know what it should be doing is expected to do.
Indeed @blowekamp, it would have been better if it had some TEST_ASSERT or TEST_EXPECT to specify the expected behavior. Like modern unit tests following the AAA - Arrange, Act, Assert pattern. (Hey, didn't "AAA" mean Almost Always Auto?!? πΈ )
Could the race condition possibly be caused by commenting out the boundary condition of the output iterator?
By commit c58537485bc04aa91ef1972094969e4ea4c4bd53 (2009). Maybe the boundary condition used to protect the outer pixels of the output region against accidental writes...?
I was able to reproduce the defect in the test, and this change solved it. Also not the annotated "write" in the reported issue.
I am not asserting that this fixes, the total algorithm, just was is reported in the issue. The algorithm clearly makes use of output that is copied from other thread's regions.
Test is now passing under TSan today: https://open.cdash.org/viewTest.php?onlydelta&buildid=10051859
Thanks!
@seanm Just wondering, do you use this filter yourself? Because we had some difficulties, trying to understand exactly how it works.
I'm afraid I don't use it. I'm just hoping to have ITK pass all its tests under TSan one day. There are only a few left to fix!
Running the itkErodeObjectMorphologyImageFilterTest test with TSan:
We see from the above that one thread is writing to 0x000107a039c8 and another is simultaneously writing to the same address. I didn't check if each thread is writing the same value or not.
Here is the relevant code, NB the fire emojis: