Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atropos fails on macOS with ANTs 2.5.0 #1627

Closed
devDonnn opened this issue Nov 17, 2023 · 9 comments
Closed

Atropos fails on macOS with ANTs 2.5.0 #1627

devDonnn opened this issue Nov 17, 2023 · 9 comments
Labels
bug Reproducible bugs

Comments

@devDonnn
Copy link

Hi,

I've been running ANTs Atropos using the downloaded GitHub release binary ants-2.5.0-macos-12-X64-clang.zip for my Mac Studio, Apple M1 Max, macOS 14.1.1:

noglob Atropos -d 3 -x brainmask.nii.gz \
-c [ 200,0.0005 ] \
-a diff.nii.gz \
-i kmeans[ 2 ] \
-s 1x2 \
-k HistogramParzenWindows[ 1,32 ] \
-m [ 0.1,1x1x1 ] \
-o [ tmpSegmentation.nii.gz,posteriors%d.nii.gz ] \
-r 1 -p Socrates[ 0 ]

However, it crashes with the following terminal output:

Atropos(6030,0x30f7b5000) malloc: *** error for object 0x600002380f00: pointer being freed was not allocated
Atropos(6030,0x30f7b5000) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort noglob Atropos -d 3 -x VISIT01/T1_brainmask.nii.gz -c [ 200,0.0005 ] -a -i

On the other hand, I had no problems with the ANTs 2.4.2 version (also downloaded GitHub release binary).

@cookpa cookpa added the bug Reproducible bugs label Jan 19, 2024
@cookpa
Copy link
Member

cookpa commented Jan 19, 2024

Hi @devDonnn , sorry for the delay in getting to this. I don't have an arm64 machine so I didn't investigate right away.

I can reproduce this though on Intel Mac and Linux. It goes away if I replace the likelihood model 'HistogramParzenWindows' with 'Gaussian'

Reproduced with

Atropos -d 3 -x tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz \
-c [ 200,0.0005 ] \
-a tpl-MNI152NLin2009cAsym_res-02_T1w.nii.gz \
-i kmeans[ 2 ] \
-k HistogramParzenWindows[ 1, 32 ] \
-m [ 0.1,1x1x1 ] \
-o [ tmpSegmentation.nii.gz,posteriors%d.nii.gz ] \
-r 1 -p Socrates[ 0 ] \
--verbose

@cookpa
Copy link
Member

cookpa commented Jan 20, 2024

Many ANTs compilations later, I have isolated the commit:

0ac02f6f4475ce3d83f871d3437d512184b51cde is the first bad commit
commit 0ac02f6f4475ce3d83f871d3437d512184b51cde
Author: Christian P. V. Christoffersen <88783438+br-cpvc@users.noreply.github.com>
Date:   Tue Dec 6 13:12:39 2022 +0000

    accelerating antsAtroposSegmentationImageFilter.hxx function GetPosteriorProbabilityImage using ITK ParallelizeImageRegion

 ImageSegmentation/antsAtroposSegmentationImageFilter.hxx | 11 +++++++++--

@cookpa
Copy link
Member

cookpa commented Jan 20, 2024

OK so to gather the information,

this fails if multi-threaded, starting at commit 0ac02f6 by @br-cpvc

Atropos -d 3 -x tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz \
-c [ 200,0.0005 ] \
-a tpl-MNI152NLin2009cAsym_res-02_T1w.nii.gz \
-i kmeans[ 2 ] \
-k HistogramParzenWindows[ 1, 32 ] \
-m [ 0.1,1x1x1 ] \
-o [ tmpSegmentation.nii.gz,posteriors%d.nii.gz ] \
-r 1 -p Socrates[ 0 ] \
--verbose

It works if I use a single thread, or if I change the likelihood to Gaussian. But it fails if using HistogramParzenWindows and multiple threads.

@cookpa
Copy link
Member

cookpa commented Jan 20, 2024

(lldb) run -d 3 -x tpl-MNI152NLin2009cAsym_res-02_desc-brain_mask.nii.gz -c [ 200,0.0005 ] -a tpl-MNI152NLin2009cAsym_res-02_T1w.nii.gz -i kmeans[ 2 ] -k HistogramParzenWindows[ 1, 32 ] -m [ 0.1,1x1x1 ] -o [ tmpSegmentation.nii.gz,posteriors%d.nii.gz ] -r 1 -p Socrates[ 0 ] --verbose
Process 77613 launched: '/Users/pcook/tmp/NOT_BACKED_UP/antsAtroposMalloc/install/bin/Atropos' (x86_64)

Running Atropos for 3-dimensional images.

Progress: 
  Iteration 0 (of 200): posterior probability = 0 (annealing temperature = 1)
Atropos(77613,0x70000d846000) malloc: *** error for object 0x600001708640: pointer being freed was not allocated
Atropos(77613,0x70000d846000) malloc: *** set a breakpoint in malloc_error_break to debug
Process 77613 stopped
* thread #2, stop reason = breakpoint 1.1
    frame #0: 0x00007ff8130345bc libsystem_malloc.dylib`malloc_error_break
libsystem_malloc.dylib`malloc_error_break:
->  0x7ff8130345bc <+0>: pushq  %rbp
    0x7ff8130345bd <+1>: movq   %rsp, %rbp
    0x7ff8130345c0 <+4>: nop    
    0x7ff8130345c1 <+5>: nopl   (%rax)
Target 0: (Atropos) stopped.
(lldb) thread backtrace
* thread #2, stop reason = breakpoint 1.1
  * frame #0: 0x00007ff8130345bc libsystem_malloc.dylib`malloc_error_break
    frame #1: 0x00007ff8130262eb libsystem_malloc.dylib`malloc_vreport + 443
    frame #2: 0x00007ff81302952b libsystem_malloc.dylib`malloc_report + 151
    frame #3: 0x00000001010edfd5 Atropos`void std::__1::__libcpp_operator_delete<void*>(__args=0x0000600001708640) at new:245:3
    frame #4: 0x00000001010edf89 Atropos`void std::__1::__do_deallocate_handle_size<>(__ptr=0x0000600001708640, __size=64) at new:269:10
    frame #5: 0x00000001010edf15 Atropos`std::__1::__libcpp_deallocate(__ptr=0x0000600001708640, __size=64, __align=8) at new:285:14
    frame #6: 0x00000001010eff8a Atropos`std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, void*> >::deallocate(this=0x0000000106304768, __p=0x0000600001708640, __n=1) at allocator.h:117:13
    frame #7: 0x00000001010efeb5 Atropos`std::__1::allocator_traits<std::__1::allocator<std::__1::__tree_node<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, void*> > >::deallocate(__a=0x0000000106304768, __p=0x0000600001708640, __n=1) at allocator_traits.h:282:13
    frame #8: 0x00000001010efde3 Atropos`std::__1::__tree<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, std::__1::__map_value_compare<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool> > >::destroy(this=0x0000000106304760, __nd=0x0000600001708640) at __tree:1804:9
    frame #9: 0x00000001010f86f5 Atropos`std::__1::__tree<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, std::__1::__map_value_compare<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool> > >::clear(this=0x0000000106304760) at __tree:1840:5
    frame #10: 0x00000001010ed315 Atropos`std::__1::map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, bool> > >::clear(this=0x0000000106304760 size=0) at map:1336:37
    frame #11: 0x00000001010ed45f Atropos`itk::ProcessObject::RestoreInputReleaseDataFlags(this=0x00000001063046b0) at itkProcessObject.cxx:1780:33
    frame #12: 0x00000001010ed1aa Atropos`itk::ProcessObject::UpdateOutputData(this=0x00000001063046b0, (null)=0x0000000106304830) at itkProcessObject.cxx:1739:9
    frame #13: 0x0000000101123a4a Atropos`itk::DataObject::UpdateOutputData(this=0x0000000106304830) at itkDataObject.cxx:388:17
    frame #14: 0x000000010018d917 Atropos`itk::ImageBase<1u>::UpdateOutputData(this=0x0000000106304830) at itkImageBase.hxx:265:23
    frame #15: 0x0000000101123757 Atropos`itk::DataObject::Update(this=0x0000000106304830) at itkDataObject.cxx:319:9
    frame #16: 0x00000001010ebe51 Atropos`itk::ProcessObject::Update(this=0x00000001063046b0) at itkProcessObject.cxx:1286:20
    frame #17: 0x000000010017e79f Atropos`itk::BSplineInterpolateImageFunction<itk::Image<float, 1u>, double, double>::SetInputImage(this=0x0000000106304550, inputData=0x0000000103e04720) at itkBSplineInterpolateImageFunction.hxx:124:26
    frame #18: 0x000000010017c280 Atropos`itk::ants::Statistics::HistogramParzenWindowsListSampleFunction<itk::Statistics::ListSample<itk::Array<float> >, float, float>::Evaluate(this=0x000060000330c000, measurement=0x000070000d845598) const at antsHistogramParzenWindowsListSampleFunction.hxx:205:29
    frame #19: 0x000000010030e7d6 Atropos`itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(this=0x00007ff7bfefa830, outputRegionForThread=0x000070000d845af0)::'lambda'(itk::ImageRegion<3u> const&)::operator()(itk::ImageRegion<3u> const&) const at antsAtroposSegmentationImageFilter.hxx:2090:70
    frame #20: 0x000000010030dced Atropos`void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(this=0x0000600006d6c098, index=0x00006000008d4100, size=0x00006000008d4120)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)::operator()(long const*, unsigned long const*) const at itkMultiThreaderBase.h:352:9
    frame #21: 0x000000010030dc1b Atropos`decltype(__f=0x0000600006d6c098, __args=0x000070000d845ca0, __args=0x000070000d845c98)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)&>(fp)(static_cast<long const*>(fp0), static_cast<unsigned long const*>(fp0))) std::__1::__invoke<void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)&, long const*, unsigned long const*>(void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)&, long const*&&, unsigned long const*&&) at type_traits:3918:1
    frame #22: 0x000000010030dbc7 Atropos`void std::__1::__invoke_void_return_wrapper<void, true>::__call<void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(__args=0x0000600006d6c098, __args=0x000070000d845ca0, __args=0x000070000d845c98)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)&, long const*, unsigned long const*>(void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)&, long const*&&, unsigned long const*&&) at invoke.h:61:9
    frame #23: 0x000000010030db77 Atropos`std::__1::__function::__alloc_func<void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*), std::__1::allocator<void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)>, void (long const*, unsigned long const*)>::operator(this=0x0000600006d6c098, __arg=0x000070000d845ca0, __arg=0x000070000d845c98)(long const*&&, unsigned long const*&&) at function.h:178:16
    frame #24: 0x000000010030c8b6 Atropos`std::__1::__function::__func<void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*), std::__1::allocator<void itk::MultiThreaderBase::ParallelizeImageRegion<3u, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&)>(itk::ImageRegion<3u> const&, itk::ants::AtroposSegmentationImageFilter<itk::Image<float, 3u>, itk::Image<unsigned int, 3u>, itk::Image<unsigned int, 3u> >::GetPosteriorProbabilityImage(unsigned int)::'lambda'(itk::ImageRegion<3u> const&), itk::ProcessObject*)::'lambda'(long const*, unsigned long const*)>, void (long const*, unsigned long const*)>::operator(this=0x0000600006d6c090, __arg=0x000070000d845ca0, __arg=0x000070000d845c98)(long const*&&, unsigned long const*&&) at function.h:352:12
    frame #25: 0x000000010110845f Atropos`std::__1::__function::__value_func<void (long const*, unsigned long const*)>::operator(this=0x0000600006d6c090, __args=0x000070000d845ca0, __args=0x000070000d845c98)(long const*&&, unsigned long const*&&) const at function.h:505:16
    frame #26: 0x00000001011029c2 Atropos`std::__1::function<void (long const*, unsigned long const*)>::operator(this=0x0000600006d6c090, __arg=0x00006000008d4100, __arg=0x00006000008d4120)(long const*, unsigned long const*) const at function.h:1182:12
    frame #27: 0x0000000101184ac6 Atropos`itk::PoolMultiThreader::ParallelizeImageRegion(this=0x0000600006d6c090)>, itk::ProcessObject*)::$_5::operator()() const at itkPoolMultiThreader.cxx:271:13
    frame #28: 0x0000000101184a65 Atropos`std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(this=0x0000600006d6c090)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda'()::operator()() const at itkThreadPool.h:92:58
    frame #29: 0x0000000101184a45 Atropos`decltype(__f=0x0000600006d6c090)>, itk::ProcessObject*)::$_5>(fp)()) std::__1::__invoke<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda'()&>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&) at type_traits:3918:1
    frame #30: 0x00000001011843a1 Atropos`std::__1::__packaged_task_func<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda'(), std::__1::allocator<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda'()>, void* ()>::operator(this=0x0000600006d6c080)() at future:1687:12
    frame #31: 0x000000010117ed0a Atropos`std::__1::__packaged_task_function<void* ()>::operator(this=0x0000600002610680)() const at future:1869:12
    frame #32: 0x000000010117ebd1 Atropos`std::__1::packaged_task<void* ()>::operator(this=0x0000600002610680)() at future:1960:24
    frame #33: 0x000000010118687d Atropos`std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(this=0x000070000d845ef8)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'()::operator()() const at itkThreadPool.h:97:43
    frame #34: 0x0000000101186845 Atropos`decltype(__f=0x000070000d845ef8)>, itk::ProcessObject*)::$_5>(fp)()) std::__1::__invoke<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'()&>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&) at type_traits:3918:1
    frame #35: 0x00000001011867fd Atropos`void std::__1::__invoke_void_return_wrapper<void, true>::__call<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(__args=0x000070000d845ef8)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'()&>(std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'()&) at invoke.h:61:9
    frame #36: 0x00000001011867cd Atropos`std::__1::__function::__alloc_func<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'(), std::__1::allocator<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'()>, void ()>::operator(this=0x000070000d845ef8)() at function.h:178:16
    frame #37: 0x00000001011853b9 Atropos`std::__1::__function::__func<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'(), std::__1::allocator<std::__1::future<std::__1::invoke_result<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>::type> itk::ThreadPool::AddWork<itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5>(itk::PoolMultiThreader::ParallelizeImageRegion(unsigned int, long const*, unsigned long const*, std::__1::function<void (long const*, unsigned long const*)>, itk::ProcessObject*)::$_5&&)::'lambda0'()>, void ()>::operator(this=0x000070000d845ef0)() at function.h:352:12
    frame #38: 0x0000000101155542 Atropos`std::__1::__function::__value_func<void ()>::operator(this=0x000070000d845ef0)() const at function.h:505:16
    frame #39: 0x0000000101151a15 Atropos`std::__1::function<void ()>::operator(this=0x000070000d845ef0)() const at function.h:1182:12
    frame #40: 0x000000010118747a Atropos`itk::ThreadPool::ThreadExecute() at itkThreadPool.cxx:211:5
    frame #41: 0x000000010118cf12 Atropos`decltype(__f=0x0000600000018048)()) std::__1::__invoke<void (*)()>(void (*&&)()) at type_traits:3918:1
    frame #42: 0x000000010118ceb5 Atropos`void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)()>(__t=size=2, (null)=__tuple_indices<> @ 0x000070000d845f68)()>&, std::__1::__tuple_indices<>) at thread:287:5
    frame #43: 0x000000010118c732 Atropos`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)()> >(__vp=0x0000600000018040) at thread:298:5
    frame #44: 0x00007ff8131fe4e1 libsystem_pthread.dylib`_pthread_start + 125
    frame #45: 0x00007ff8131f9f6b libsystem_pthread.dylib`thread_start + 15

Debug stack trace from lldb. Looking at frame #18. Can't do much more for now but will look again later

@cookpa
Copy link
Member

cookpa commented Jan 21, 2024

Looks like the problem is here

this->m_Interpolator->SetInputImage(this->m_HistogramImages[d]);

Multiple threads are using the same m_Interpolator object simultaneously. Using a local interpolator (as is done in antsJointHistogramParzenWindowsListSampleFunction.hxx) fixes the malloc error but makes the overall process much slower than it was when single-threaded.

I'm not sure of the best way to proceed here, @ntustison would you mind taking a look when you have some time? Thanks

@ntustison
Copy link
Member

Will do. Thanks for tracking this down @cookpa

@cookpa
Copy link
Member

cookpa commented Jan 21, 2024

Thanks! FYI ManifoldParzenWindows also seg faults, but I haven't used that one much.

@cookpa
Copy link
Member

cookpa commented Jan 22, 2024

@devDonnn I believe this is fixed now with #1663

@cookpa
Copy link
Member

cookpa commented Jan 22, 2024

Results look good and consistent with v2.4.0

@cookpa cookpa closed this as completed Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Reproducible bugs
Projects
None yet
Development

No branches or pull requests

3 participants