Program Listing for File parallel.hpp
↰ Return to documentation for file (src/utils/parallel.hpp)
//
// Created by Zack Williams on 27/11/2020.
//
#ifndef UW12_PARALLEL_HPP
#define UW12_PARALLEL_HPP
#include <functional>
#ifdef USE_TBB
#include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h>
#include <tbb/task_arena.h>
#endif
namespace uw12::parallel {
inline void parallel_for(
size_t start,
size_t stop,
const std::function<void(size_t)> &func,
bool parallel = true
) {
#ifdef USE_TBB
if (parallel) {
const auto range = tbb::blocked_range(start, stop);
const auto parallel_fn = [&func](const tbb::blocked_range<size_t> &block) {
for (size_t i = block.begin(); i != block.end(); ++i) {
func(i);
}
};
tbb::parallel_for(range, parallel_fn);
} else
#elif USE_OMP
if (parallel) {
#pragma omp parallel
{
#pragma omp for
for (size_t i = start; i < stop; ++i) {
func(i);
}
}
} else
#endif
{
for (size_t i = start; i < stop; ++i) {
func(i);
}
}
}
template <typename ReturnType>
ReturnType parallel_sum(
const size_t start,
const size_t stop,
const ReturnType &identity,
const std::function<ReturnType(size_t)> &func,
const bool parallel = true
) {
#ifdef USE_TBB
if (parallel) {
const auto red_fn = [](ReturnType left,
const ReturnType &right) -> ReturnType {
left += right;
return left;
};
const auto range = tbb::blocked_range(start, stop);
const auto parallel_fn =
[&func](
const tbb::blocked_range<size_t> &blocked_range, ReturnType result
) -> ReturnType {
for (size_t i = blocked_range.begin(); i != blocked_range.end(); i++) {
result += func(i);
}
return result;
};
return tbb::parallel_reduce(range, identity, parallel_fn, red_fn);
} else
#elif USE_OMP
if (parallel) {
ReturnType result(identity);
#pragma omp declare reduction(sum:ReturnType : omp_out += omp_in) \
initializer(omp_priv(omp_orig))
#pragma omp parallel reduction(sum : result)
{
#pragma omp for
for (size_t i = start; i < stop; ++i) {
result += func(i);
}
}
return result;
} else
#endif
{
ReturnType result(identity);
for (size_t i = start; i < stop; ++i) {
result += func(i);
}
return result;
}
}
template <typename ReturnType>
ReturnType parallel_sum_2d(
const size_t start1,
const size_t stop1,
const size_t start2,
const size_t stop2,
const ReturnType &identity,
const std::function<ReturnType(size_t, size_t)> &func,
const bool parallel = true
) {
const auto parallel_fn = [&func, start2, stop2, &identity](const size_t i
) -> ReturnType {
ReturnType result(identity);
for (size_t j = start2; j < stop2; ++j) {
result += func(i, j);
}
return result;
};
return parallel_sum<ReturnType>(
start1, stop1, identity, parallel_fn, parallel
);
}
template <typename Func>
void isolate(Func &&func) {
#ifdef USE_TBB
tbb::this_task_arena::isolate([&func] { func(); });
#else
func();
#endif
}
} // namespace uw12::parallel
#endif // UW12_PARALLEL_HPP