Skip to content

Commit

Permalink
Wrap Shared with MutexProtected
Browse files Browse the repository at this point in the history
  • Loading branch information
daljit46 committed Feb 2, 2024
1 parent a123bb4 commit 378757e
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 96 deletions.
183 changes: 89 additions & 94 deletions core/algo/threaded_loop.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "algo/iterator.h"
#include "algo/loop.h"
#include "debug.h"
#include "mutexprotected.h"
#include "thread.h"

namespace MR {
Expand Down Expand Up @@ -315,7 +316,6 @@ template <class OuterLoopType> struct ThreadedLoopRunOuter {
return;
}

std::mutex mutex;
ProgressBar::SwitchToMultiThreaded progress_functions;

struct Shared {
Expand All @@ -326,9 +326,7 @@ template <class OuterLoopType> struct ThreadedLoopRunOuter {
~Shared() = default;
Iterator &iterator;
decltype(outer_loop(iterator)) loop;
std::mutex &mutex;
FORCE_INLINE bool next(Iterator &pos) {
std::lock_guard<std::mutex> lock(mutex);
if (loop) {
assign_pos_of(iterator, loop.axes).to(pos);
++loop;
Expand All @@ -337,107 +335,104 @@ template <class OuterLoopType> struct ThreadedLoopRunOuter {
return false;
}
Iterator get_iterator() const {
std::lock_guard<std::mutex> lock(mutex);
return iterator;
}

} shared = {iterator, outer_loop(iterator), mutex};

struct PerThread {
PerThread(const PerThread &) = default;
PerThread(PerThread &&) noexcept = default;
PerThread &operator=(const PerThread &) = delete;
PerThread &operator=(PerThread &&) = delete;
~PerThread() = default;
Shared &shared;
typename std::remove_reference<Functor>::type func;
void execute() {
auto pos = shared.get_iterator();
while (shared.next(pos))
func(pos);
MutexProtected<Shared> shared = {iterator, outer_loop(iterator)};

struct PerThread {
PerThread(const PerThread &) = default;
PerThread(PerThread &&) noexcept = default;
PerThread &operator=(const PerThread &) = delete;
PerThread &operator=(PerThread &&) = delete;
~PerThread() = default;
MutexProtected<Shared> &shared;
typename std::remove_reference<Functor>::type func;
void execute() {
auto pos = shared.lock()->iterator;
while (shared.lock()->next(pos))
func(pos);
}
} loop_thread = {shared, functor};

auto threads = Thread::run(Thread::multi(loop_thread), "loop threads");

__manage_progress(&shared.lock()->loop, &threads);
threads.wait();
}
} loop_thread = {shared, functor};

auto threads = Thread::run(Thread::multi(loop_thread), "loop threads");

__manage_progress(&shared.loop, &threads);
threads.wait();
//! invoke \a functor (const Iterator& pos) per voxel <em> in the outer axes only</em>
template <class Functor, class... ImageType> void run(Functor &&functor, ImageType &&...vox) {
ThreadedLoopRunInner<sizeof...(ImageType),
typename std::remove_reference<Functor>::type,
typename std::remove_reference<ImageType>::type...>
loop_thread(outer_loop.axes, inner_axes, functor, vox...);
run_outer(loop_thread);
check_app_exit_code();
}
};
} // namespace

//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop(vector<size_t>()))>
ThreadedLoop(const HeaderType &source, const vector<size_t> &outer_axes, const vector<size_t> &inner_axes) {
return {source, Loop(outer_axes), inner_axes};
}

//! invoke \a functor (const Iterator& pos) per voxel <em> in the outer axes only</em>
template <class Functor, class... ImageType> void run(Functor &&functor, ImageType &&...vox) {
ThreadedLoopRunInner<sizeof...(ImageType),
typename std::remove_reference<Functor>::type,
typename std::remove_reference<ImageType>::type...>
loop_thread(outer_loop.axes, inner_axes, functor, vox...);
run_outer(loop_thread);
check_app_exit_code();
//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop(vector<size_t>()))>
ThreadedLoop(const HeaderType &source, const vector<size_t> &axes, size_t num_inner_axes = 1) {
return {source, Loop(get_outer_axes(axes, num_inner_axes)), get_inner_axes(axes, num_inner_axes)};
}
};
} // namespace

//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop(vector<size_t>()))>
ThreadedLoop(const HeaderType &source, const vector<size_t> &outer_axes, const vector<size_t> &inner_axes) {
return {source, Loop(outer_axes), inner_axes};
}

//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop(vector<size_t>()))>
ThreadedLoop(const HeaderType &source, const vector<size_t> &axes, size_t num_inner_axes = 1) {
return {source, Loop(get_outer_axes(axes, num_inner_axes)), get_inner_axes(axes, num_inner_axes)};
}

//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop(vector<size_t>()))>
ThreadedLoop(const HeaderType &source,
size_t from_axis = 0,
size_t to_axis = std::numeric_limits<size_t>::max(),
size_t num_inner_axes = 1) {
return {source,
Loop(get_outer_axes(source, num_inner_axes, from_axis, to_axis)),
get_inner_axes(source, num_inner_axes, from_axis, to_axis)};
}
//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop(vector<size_t>()))>
ThreadedLoop(const HeaderType &source,
size_t from_axis = 0,
size_t to_axis = std::numeric_limits<size_t>::max(),
size_t num_inner_axes = 1) {
return {source,
Loop(get_outer_axes(source, num_inner_axes, from_axis, to_axis)),
get_inner_axes(source, num_inner_axes, from_axis, to_axis)};
}

//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop("", vector<size_t>()))> ThreadedLoop(const std::string &progress_message,
const HeaderType &source,
const vector<size_t> &outer_axes,
const vector<size_t> &inner_axes) {
return {source, Loop(progress_message, outer_axes), inner_axes};
}
//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop("", vector<size_t>()))> ThreadedLoop(const std::string &progress_message,
const HeaderType &source,
const vector<size_t> &outer_axes,
const vector<size_t> &inner_axes) {
return {source, Loop(progress_message, outer_axes), inner_axes};
}

//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop("", vector<size_t>()))> ThreadedLoop(const std::string &progress_message,
const HeaderType &source,
const vector<size_t> &axes,
size_t num_inner_axes = 1) {
return {source, Loop(progress_message, get_outer_axes(axes, num_inner_axes)), get_inner_axes(axes, num_inner_axes)};
}
//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop("", vector<size_t>()))> ThreadedLoop(const std::string &progress_message,
const HeaderType &source,
const vector<size_t> &axes,
size_t num_inner_axes = 1) {
return {source, Loop(progress_message, get_outer_axes(axes, num_inner_axes)), get_inner_axes(axes, num_inner_axes)};
}

//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop("", vector<size_t>()))>
ThreadedLoop(const std::string &progress_message,
const HeaderType &source,
size_t from_axis = 0,
size_t to_axis = std::numeric_limits<size_t>::max(),
size_t num_inner_axes = 1) {
return {source,
Loop(progress_message, get_outer_axes(source, num_inner_axes, from_axis, to_axis)),
get_inner_axes(source, num_inner_axes, from_axis, to_axis)};
}
//! Multi-threaded loop object
//* \sa image_thread_looping for details */
template <class HeaderType>
inline ThreadedLoopRunOuter<decltype(Loop("", vector<size_t>()))>
ThreadedLoop(const std::string &progress_message,
const HeaderType &source,
size_t from_axis = 0,
size_t to_axis = std::numeric_limits<size_t>::max(),
size_t num_inner_axes = 1) {
return {source,
Loop(progress_message, get_outer_axes(source, num_inner_axes, from_axis, to_axis)),
get_inner_axes(source, num_inner_axes, from_axis, to_axis)};
}

} // namespace MR

Expand Down
2 changes: 1 addition & 1 deletion testing/scripts/data
Submodule data updated 35 files
+ dwi2mask/mtnorm_default_mask.mif.gz
+ dwi2mask/mtnorm_default_tissuesum.mif.gz
+ dwi2mask/mtnorm_initmask_mask.mif.gz
+ dwi2mask/mtnorm_initmask_tissuesum.mif.gz
+ dwi2mask/mtnorm_lmax600_mask.mif.gz
+ dwi2mask/mtnorm_lmax600_tissuesum.mif.gz
+ dwibiascorrect/mtnorm/default_bias.mif.gz
+ dwibiascorrect/mtnorm/default_out.mif.gz
+ dwibiascorrect/mtnorm/lmax600_bias.mif.gz
+ dwibiascorrect/mtnorm/lmax600_out.mif.gz
+ dwibiascorrect/mtnorm/masked_bias.mif.gz
+ dwibiascorrect/mtnorm/masked_out.mif.gz
+ dwibiasnormmask/3iters_bias.mif.gz
+ dwibiasnormmask/3iters_mask.mif.gz
+ dwibiasnormmask/3iters_out.mif.gz
+0 −2 dwibiasnormmask/3iters_scale.txt
+ dwibiasnormmask/3iters_tissuesum.mif.gz
+ dwibiasnormmask/default_bias.mif.gz
+ dwibiasnormmask/default_mask.mif.gz
+ dwibiasnormmask/default_out.mif.gz
+0 −2 dwibiasnormmask/default_scale.txt
+ dwibiasnormmask/default_tissuesum.mif.gz
+ dwibiasnormmask/lmax600_bias.mif.gz
+ dwibiasnormmask/lmax600_mask.mif.gz
+ dwibiasnormmask/lmax600_out.mif.gz
+0 −2 dwibiasnormmask/lmax600_scale.txt
+ dwibiasnormmask/lmax600_tissuesum.mif.gz
+ dwinormalise/individual/out.mif.gz
+ dwinormalise/individual/percentile.mif.gz
+ dwinormalise/mtnorm/default_out.mif.gz
+0 −2 dwinormalise/mtnorm/default_scale.txt
+ dwinormalise/mtnorm/lmax600_out.mif.gz
+0 −2 dwinormalise/mtnorm/lmax600_scale.txt
+ dwinormalise/mtnorm/masked_out.mif.gz
+0 −2 dwinormalise/mtnorm/masked_scale.txt

0 comments on commit 378757e

Please sign in to comment.