-
Notifications
You must be signed in to change notification settings - Fork 191
tckglobal: Fix operation #3172
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
tckglobal: Fix operation #3172
Conversation
|
Wasn't able to resolve assertion failure at first sitting. If my interpretation is correct, and the purpose of the
, then perhaps: T_s2g = H.transform() * newspacing;
T_s2g = T_s2g.inverse().translate(shift);should be: T_s2g = H.transform() * newspacing;
T_s2g.translate(-shift);
T_s2g = T_s2g.inverse();? |
|
I think I managed to reproduce the assertion error, and I implemented a fix. @Lestropie can you test if this works for you? |
|
There looks to still be a race condition somewhere. Backtrace: |
|
@dchristiaens If it's a data race (and not a logic race condition), it may be helpful to build and test with thread sanitizer: |
|
I ran with TSAN on my Linux machine and it confirmed that indeed there is a data race: WARNING: ThreadSanitizer: data race (pid=601769)
Read of size 4 at 0x7250001006d4 by thread T35:
#0 MR::DWI::Tractography::GT::InternalEnergyComputer::scanNeighbourhood(MR::DWI::Tractography::GT::Particle const*, int, double) <null> (tckglobal+0xfe758) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#1 MR::DWI::Tractography::GT::InternalEnergyComputer::stageConnect(MR::DWI::Tractography::GT::ParticleEnd const&, MR::DWI::Tractography::GT::ParticleEnd&) <null> (tckglobal+0xfdc84) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#2 MR::DWI::Tractography::GT::EnergySumComputer::stageConnect(MR::DWI::Tractography::GT::ParticleEnd const&, MR::DWI::Tractography::GT::ParticleEnd&) <null> (tckglobal+0x1321d2) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#3 MR::DWI::Tractography::GT::MHSampler::connect() <null> (tckglobal+0xf3e4d) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#4 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0xf1d72) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#5 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0xf1ac7) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#6 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x13f9a3) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#7 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x13f89e) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#8 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x1385a0) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#9 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x1386dd) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#10 pthread_once <null> (tckglobal+0x714fd) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#11 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x1382ed) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#12 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x13f5fb) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x13fb47) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#14 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Previous write of size 4 at 0x7250001006d4 by thread T33:
#0 MR::DWI::Tractography::GT::ParticleGrid::shift(MR::DWI::Tractography::GT::Particle*, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x195f4d) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#1 MR::DWI::Tractography::GT::MHSampler::optshift() <null> (tckglobal+0xf3a08) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#2 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0xf1d46) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#3 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0xf1ac7) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#4 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x13f9a3) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#5 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x13f89e) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#6 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x1385a0) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#7 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x1386dd) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#8 pthread_once <null> (tckglobal+0x714fd) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#9 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x1382ed) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#10 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x13f5fb) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x13fb47) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#12 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Location is heap block of size 480 at 0x725000100600 allocated by thread T26:
#0 operator new(unsigned long) <null> (tckglobal+0xecebb) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#1 void std::deque<MR::DWI::Tractography::GT::Particle, std::allocator<MR::DWI::Tractography::GT::Particle>>::_M_push_back_aux<Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&>(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x198654) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#2 MR::DWI::Tractography::GT::ParticlePool::create(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x197bcf) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#3 MR::DWI::Tractography::GT::ParticleGrid::add(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x1952c5) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#4 MR::DWI::Tractography::GT::MHSampler::birth() <null> (tckglobal+0xf23a9) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#5 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0xf1cbc) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#6 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0xf1ac7) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#7 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x13f9a3) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#8 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x13f89e) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#9 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x1385a0) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#10 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x1386dd) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#11 pthread_once <null> (tckglobal+0x714fd) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#12 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x1382ed) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#13 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x13f5fb) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#14 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x13fb47) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#15 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Thread T35 (tid=601827, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x13e033) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#4 run() <null> (tckglobal+0x10d48a) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#5 main <null> (tckglobal+0x10097a) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
Thread T33 (tid=601825, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x13e033) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#4 run() <null> (tckglobal+0x10d48a) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#5 main <null> (tckglobal+0x10097a) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
Thread T26 (tid=601818, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x13e033) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#4 run() <null> (tckglobal+0x10d48a) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
#5 main <null> (tckglobal+0x10097a) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2)
SUMMARY: ThreadSanitizer: data race (/home/ds23/Documents/Dev/mrtrix3-master/bin/tckglobal+0xfe758) (BuildId: 1b7ea2c1e22d1667253812c05dda0646e4dcc8a2) in MR::DWI::Tractography::GT::InternalEnergyComputer::scanNeighbourhood(MR::DWI::Tractography::GT::Particle const*, int, double)EDIT: actually we have multiple data races. WARNING: ThreadSanitizer: data race (pid=609578)
Read of size 4 at 0x7f9d78c25730 by thread T29:
#0 Eigen::Matrix<double, -1, 1, 0, -1, 1>& Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>::operator+=<MR::Image<float>>(MR::Helper::ConstRow<MR::Image<float>> const&) <null> (tckglobal+0x16a618) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::DWI::Tractography::GT::ExternalEnergyComputer::add2vox(Eigen::Matrix<int, 3, 1, 0, 3, 1> const&, double) <null> (tckglobal+0x15b62d) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#2 MR::DWI::Tractography::GT::ExternalEnergyComputer::add(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, double) <null> (tckglobal+0x15a889) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#3 MR::DWI::Tractography::GT::ExternalEnergyComputer::stageShift(MR::DWI::Tractography::GT::Particle const*, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x171bf7) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 MR::DWI::Tractography::GT::EnergySumComputer::stageShift(MR::DWI::Tractography::GT::Particle const*, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x14467a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 MR::DWI::Tractography::GT::MHSampler::randshift() <null> (tckglobal+0x19203a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0x190e9a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0x190c47) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#8 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x14c573) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#9 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x14c46e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#10 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x10da80) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#11 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x10dbbd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#12 pthread_once <null> (tckglobal+0x714fd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#13 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x10d7cd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#14 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x14c1cb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#15 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x14c717) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#16 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Previous write of size 4 at 0x7f9d78c25730 by thread T40:
#0 MR::DWI::Tractography::GT::ExternalEnergyComputer::acceptChanges() <null> (tckglobal+0x1597f8) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::DWI::Tractography::GT::EnergySumComputer::acceptChanges() <null> (tckglobal+0x1448cc) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#2 MR::DWI::Tractography::GT::MHSampler::optshift() <null> (tckglobal+0x192b67) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#3 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0x190ec6) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0x190c47) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x14c573) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x14c46e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x10da80) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#8 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x10dbbd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#9 pthread_once <null> (tckglobal+0x714fd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#10 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x10d7cd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#11 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x14c1cb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#12 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x14c717) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#13 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Location is heap block of size 445500 at 0x7f9d78c24000 allocated by main thread:
#0 operator new[](unsigned long) <null> (tckglobal+0xecfab) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::ImageIO::Scratch::load(MR::Header const&, unsigned long) <null> (libmrtrix.so+0x153cb6) (BuildId: 8f78ae4ca8b8345dc11741777e4f90f2262dd645)
#2 MR::ImageIO::Base::open(MR::Header const&, unsigned long) <null> (libmrtrix.so+0x3854ba) (BuildId: 8f78ae4ca8b8345dc11741777e4f90f2262dd645)
#3 MR::Image<float>::Buffer::Buffer(MR::Header&, bool) <null> (tckglobal+0x15189e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 MR::Image<float> MR::Header::get_image<float>(bool) <null> (tckglobal+0x151415) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 MR::DWI::Tractography::GT::ExternalEnergyComputer::ExternalEnergyComputer(MR::DWI::Tractography::GT::Stats&, MR::Header&, MR::DWI::Tractography::GT::Properties const&) <null> (tckglobal+0x154528) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 run() <null> (tckglobal+0x121926) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
Thread T29 (tid=609610, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x14ac03) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 run() <null> (tckglobal+0x12232a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
Thread T40 (tid=609621, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x14ac03) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 run() <null> (tckglobal+0x122650) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
SUMMARY: ThreadSanitizer: data race (/home/ds23/Documents/Dev/mrtrix3-master/bin/tckglobal+0x16a618) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770) in Eigen::Matrix<double, -1, 1, 0, -1, 1>& Eigen::MatrixBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>>::operator+=<MR::Image<float>>(MR::Helper::ConstRow<MR::Image<float>> const&)
WARNING: ThreadSanitizer: data race (pid=609578)
Read of size 4 at 0x729400001730 by thread T29:
#0 MR::DWI::Tractography::GT::ExternalEnergyComputer::eval() <null> (tckglobal+0x15c3e0) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::DWI::Tractography::GT::ExternalEnergyComputer::stageShift(MR::DWI::Tractography::GT::Particle const*, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x171c15) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#2 MR::DWI::Tractography::GT::EnergySumComputer::stageShift(MR::DWI::Tractography::GT::Particle const*, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0x14467a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#3 MR::DWI::Tractography::GT::MHSampler::randshift() <null> (tckglobal+0x19203a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0x190e9a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0x190c47) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x14c573) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x14c46e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#8 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x10da80) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#9 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x10dbbd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#10 pthread_once <null> (tckglobal+0x714fd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#11 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x10d7cd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#12 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x14c1cb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x14c717) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#14 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Previous write of size 4 at 0x729400001730 by thread T40:
#0 MR::DWI::Tractography::GT::ExternalEnergyComputer::acceptChanges() <null> (tckglobal+0x159ad6) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::DWI::Tractography::GT::EnergySumComputer::acceptChanges() <null> (tckglobal+0x1448cc) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#2 MR::DWI::Tractography::GT::MHSampler::optshift() <null> (tckglobal+0x192b67) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#3 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0x190ec6) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0x190c47) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x14c573) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x14c46e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x10da80) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#8 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x10dbbd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#9 pthread_once <null> (tckglobal+0x714fd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#10 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x10d7cd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#11 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x14c1cb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#12 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x14c717) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#13 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Location is heap block of size 9900 at 0x729400000000 allocated by main thread:
#0 operator new[](unsigned long) <null> (tckglobal+0xecfab) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::ImageIO::Scratch::load(MR::Header const&, unsigned long) <null> (libmrtrix.so+0x153cb6) (BuildId: 8f78ae4ca8b8345dc11741777e4f90f2262dd645)
#2 MR::ImageIO::Base::open(MR::Header const&, unsigned long) <null> (libmrtrix.so+0x3854ba) (BuildId: 8f78ae4ca8b8345dc11741777e4f90f2262dd645)
#3 MR::Image<float>::Buffer::Buffer(MR::Header&, bool) <null> (tckglobal+0x15189e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 MR::Image<float> MR::Header::get_image<float>(bool) <null> (tckglobal+0x151415) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 MR::DWI::Tractography::GT::ExternalEnergyComputer::ExternalEnergyComputer(MR::DWI::Tractography::GT::Stats&, MR::Header&, MR::DWI::Tractography::GT::Properties const&) <null> (tckglobal+0x154cc5) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 run() <null> (tckglobal+0x121926) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
Thread T29 (tid=609610, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x14ac03) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 run() <null> (tckglobal+0x12232a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
Thread T40 (tid=609621, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x14ac03) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 run() <null> (tckglobal+0x122650) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
SUMMARY: ThreadSanitizer: data race (/home/ds23/Documents/Dev/mrtrix3-master/bin/tckglobal+0x15c3e0) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770) in MR::DWI::Tractography::GT::ExternalEnergyComputer::eval()
WARNING: ThreadSanitizer: data race (pid=609578)
Read of size 8 at 0x725000051c30 by thread T23:
#0 MR::DWI::Tractography::GT::MHSampler::moveRandom(MR::DWI::Tractography::GT::Particle const*, Eigen::Matrix<float, 3, 1, 0, 3, 1>&, Eigen::Matrix<float, 3, 1, 0, 3, 1>&) <null> (tckglobal+0x194853) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::DWI::Tractography::GT::MHSampler::randshift() <null> (tckglobal+0x191e04) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#2 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0x190e9a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#3 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0x190c47) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x14c573) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x14c46e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x10da80) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x10dbbd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#8 pthread_once <null> (tckglobal+0x714fd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#9 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x10d7cd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#10 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x14c1cb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x14c717) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#12 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Previous write of size 4 at 0x725000051c30 by thread T34:
#0 MR::DWI::Tractography::GT::ParticleGrid::shift(MR::DWI::Tractography::GT::Particle*, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0xef32e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 MR::DWI::Tractography::GT::MHSampler::randshift() <null> (tckglobal+0x19221c) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#2 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0x190e9a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#3 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0x190c47) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x14c573) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x14c46e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x10da80) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x10dbbd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#8 pthread_once <null> (tckglobal+0x714fd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#9 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x10d7cd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#10 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x14c1cb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#11 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x14c717) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#12 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Location is heap block of size 480 at 0x725000051c00 allocated by thread T24:
#0 operator new(unsigned long) <null> (tckglobal+0xecebb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 void std::deque<MR::DWI::Tractography::GT::Particle, std::allocator<MR::DWI::Tractography::GT::Particle>>::_M_push_back_aux<Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&>(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0xf3bb4) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#2 MR::DWI::Tractography::GT::ParticlePool::create(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0xf108f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#3 MR::DWI::Tractography::GT::ParticleGrid::add(Eigen::Matrix<float, 3, 1, 0, 3, 1> const&, Eigen::Matrix<float, 3, 1, 0, 3, 1> const&) <null> (tckglobal+0xee785) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 MR::DWI::Tractography::GT::MHSampler::birth() <null> (tckglobal+0x191529) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 MR::DWI::Tractography::GT::MHSampler::next() <null> (tckglobal+0x190e3c) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#6 MR::DWI::Tractography::GT::MHSampler::execute() <null> (tckglobal+0x190c47) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#7 std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::operator()() const <null> (tckglobal+0x14c573) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#8 std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>>::_M_invoke(std::_Any_data const&) <null> (tckglobal+0x14c46e) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#9 std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) <null> (tckglobal+0x10da80) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#10 std::once_flag::_Prepare_execution::_Prepare_execution<void std::call_once<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::once_flag&, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&)::'lambda'()>(void (std::__future_base::_State_baseV2::*&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*))::'lambda'()::__invoke() <null> (tckglobal+0x10dbbd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#11 pthread_once <null> (tckglobal+0x714fd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#12 std::__future_base::_State_baseV2::_M_set_result(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>, bool) <null> (tckglobal+0x10d7cd) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#13 std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::_M_run() <null> (tckglobal+0x14c1cb) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#14 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>::*)(), std::__future_base::_Async_state_impl<std::thread::_Invoker<std::tuple<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>>, void>*>>>::_M_run() <null> (tckglobal+0x14c717) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#15 execute_native_thread_routine /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:104:18 (libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
Thread T23 (tid=609604, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x14ac03) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 run() <null> (tckglobal+0x12232a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
Thread T34 (tid=609615, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x14ac03) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 run() <null> (tckglobal+0x12232a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
Thread T24 (tid=609605, running) created by main thread at:
#0 pthread_create <null> (tckglobal+0x6d93f) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#1 __gthread_create /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/include/x86_64-linux-gnu/bits/gthr-default.h:676:35 (libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
#2 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) /build/gcc-14-ig5ci0/gcc-14-14.2.0/build/x86_64-linux-gnu/libstdc++-v3/src/c++11/../../../../../src/libstdc++-v3/src/c++11/thread.cc:172:37 (libstdc++.so.6+0xeceb0)
#3 std::future<std::__invoke_result<std::decay<void (MR::DWI::Tractography::GT::MHSampler::*)()>::type, std::decay<MR::DWI::Tractography::GT::MHSampler*>::type>::type> std::async<void (MR::DWI::Tractography::GT::MHSampler::*)(), MR::DWI::Tractography::GT::MHSampler*>(std::launch, void (MR::DWI::Tractography::GT::MHSampler::*&&)(), MR::DWI::Tractography::GT::MHSampler*&&) <null> (tckglobal+0x14ac03) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#4 run() <null> (tckglobal+0x12232a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
#5 main <null> (tckglobal+0x11581a) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770)
SUMMARY: ThreadSanitizer: data race (/home/ds23/Documents/Dev/mrtrix3-master/bin/tckglobal+0x194853) (BuildId: d2890daaa617025bb34f56b296f662dfc37e2770) in MR::DWI::Tractography::GT::MHSampler::moveRandom(MR::DWI::Tractography::GT::Particle const*, Eigen::Matrix<float, 3, 1, 0, 3, 1>&, Eigen::Matrix<float, 3, 1, 0, 3, 1>&) |
- unlock() must hold the mutex because it writes lockcentres[idx].second - ~SpatialLock() should also lock before clearing lockcentres to avoid a race if another thread is concurrently in try_lock()/unlock().
This class holds a reference and relies on its destructor to call `unlock`. The default copy/move will copy idx and the reference leading to double unlock() calls.
ParticlePool::size() was a const accessor that read pool.size() and avail.size() without taking the pool mutex. Other threads can call create()/destroy() which modify pool/avail under the mutex.
|
I had a look at the code yesterday, and all the threading issues identified by TSAN are quite difficult to fix without non-trivial changes. The code employs a shared-state concurrency logic without guaranteeing proper synchronisation and it lacks a clear ownership model. For example, the Another issue is that the core logic involves operations that must be treated as a single, indivisible atomic transaction, but the code executes them as a sequence of separate and unprotected steps. In Also, we're leaking raw pointers to internal data stored in a vector (in I'm unsure of how to fix these problems, but if we want to make the code more maintainable for the future, we should reconsider the overall design of it. |
|
@dchristiaens Would it be acceptable to disable multi-threading within |
|
Sorry for the late reply - this is a very busy month for me.. Thanks @daljit46 for looking into this. It's clear there is an issue here, although I don't find it to be particularly problematic in practice. Some thoughts on the specific points you listed:
This is precisely what SpatialLock is intended to prevent. As long as the distance threshold is set large enough, no two particles should ever compete to connect to the same (third) particle.
This should likewise be prevented by the SpatialLock.
I don't fully understand what you mean. Memory is managed by the ParticlePool class, which uses a @Lestropie I agree that it's good to add a warning. However, I don't think making single-threaded the default is a good idea, as this would have a strong impact on run time and be prohibitive in most practical use cases. |
tckglobal: Disable multi-threading by default
|
I have added a bit of code to make sure that the SpatialLock also covers the grid spacing. It's possible that I broke this in my earlier commit a few weeks ago, in which the grid sise was redefined to take the image voxel size into account too. I can not reproduce the issue on my system, so I'm curious to see what the CI will think of this. |
That's good to know. If this is a theoretical guarantee that, given a minimum radius, two threads will never try to connect to the same neighbour, then I think that we can ignore that point. At least, when I tested a couple of weeks ago, TSAN reported that this was happening in happening in practice (i.e. two threads were in contention in the
In this case, I was referring to the
I tested your changes with TSAN on my machine, and there are a lot of reports of data races, unfortunately. |
This provides a more lightweight alternative to a full-blown mutex, useful in cases where there may be a very large number of small objects that each need their own thread protection. It relies on std::atomic_flag, and only takes up a single byte. It should only be used sparingly and in cases where collisions are expected to be rare, since spinning threads will keep running.
|
Just had some fun with thread sanitizer to try to fix up all the race conditions here. I've managed to get a clean run with the changes I've just pushed 🎉 As part of this exercise, I've also identified a race condition in the threaded loop code. I'll commit that fix shortly as a separate PR. @dchristiaens: I've no idea whether the changes I've made here break anything, I've only tested that it runs to completion with no errors reported from thread sanitizer. I've also not looked into how much of an impact these changes might have made to performance. It would be wise to verify that everything still works as expected... |
This uses the new SpinLock class to protect multi-threaded access to individual particles, adds a mutex to protect each element of the particle grid, and uses a std::deque instead of a std::vector to store the particles within each element of the particle grid to avoid the potential for pointers becoming invalid when adding / removing particles.
9558deb to
50b5de2
Compare
On my system, your changes result in the tests taking about 4x longer, but no data races :) |
|
Ouch. That's quite a hit... Is that running with the code compiled for release...? |
|
Yes, but interestingly I found this article and adapting the code shown at the bottom: If I use this EDIT: C++11 apparently has std::this_thread::yield() which works fine too (it's apparently an OS level scheduling hint rather than architecture-based). |
|
UPDATE: never mind, I tested again with a full clean build, and your code is only marginally slower. So ignore the comment above. |
|
Just checking: marginally slower than your alternative spin lock, or than the original non-thread-safe version? |
I meant against the alternative spin lock, but I think the difference is well within noise intervals, so they perform roughly the same. The current tip is a little slower (on my M2 Pro) than the thread-unsafe version: This runs (from within |
|
Thanks Donald - once again you proved yourself to be the most accomplished programmer of us all! I've done a few full-brain tests. The code is indeed a bit slower than it used to be, but that's a fair sacrifice to make. The output looks indistinguishable from the old multi-threaded version, so the changes are all fine. I find it equally reassuring to know that the race conditions in the old version did not severely affect the output, which I assume is because the MH sampler is robust to such random perturbations of the system state. |
Changes in 2be257c made as part of #3011 resulted in there being two separate attempts to construct an Image class from the same input header.
Fixes #3171.
Classic case of many implicit casts from
ImagetoHeaderdue to not explicitly creating aHeaderat commencement ofrun(), and usingImagefor class construction where aHeaderwould have sufficed. 2be257c was supposed to clean some of these up but clearly I didn't look closely enough or verify.I tried adding a CI test for
tckglobalutilising the data indwi2fod/msmt/, but I get what seems to me to be an unrelated assertion failure at:https://github.com/MRtrix3/mrtrix3/blob/3.0.7/src/dwi/tractography/GT/particlegrid.h#L94
Will see if I can figure it out, but @dchristiaens might have a better shot.