99#ifdef SUBPAR_CUSTOM_PARALLELIZE_RANGE
100 if constexpr(nothrow_) {
101#ifdef SUBPAR_CUSTOM_PARALLELIZE_RANGE_NOTHROW
102 SUBPAR_CUSTOM_PARALLELIZE_RANGE_NOTHROW(num_workers, num_tasks, run_task_range);
104 SUBPAR_CUSTOM_PARALLELIZE_RANGE(num_workers, num_tasks, run_task_range);
107 SUBPAR_CUSTOM_PARALLELIZE_RANGE(num_workers, num_tasks, run_task_range);
111 if (num_tasks == 0) {
115 if (num_workers <= 1 || num_tasks == 1) {
116 run_task_range(0, 0, num_tasks);
121 Task_ tasks_per_worker = 1;
123 if (sanisizer::is_greater_than_or_equal(num_workers, num_tasks)) {
124 num_workers = num_tasks;
126 tasks_per_worker = num_tasks / num_workers;
127 remainder = num_tasks % num_workers;
132 if constexpr(nothrow_) {
135 return sanisizer::create<std::vector<std::exception_ptr> >(num_workers);
139#if defined(_OPENMP) && !defined(SUBPAR_NO_OPENMP_RANGE) && !defined(SUBPAR_NO_OPENMP)
140#define SUBPAR_USES_OPENMP 1
141#define SUBPAR_USES_OPENMP_RANGE 1
145 #pragma omp parallel for num_threads(num_workers)
146 for (
int w = 0; w < num_workers; ++w) {
147 const Task_ start = w * tasks_per_worker + (w < remainder ? w : remainder);
148 const Task_ length = tasks_per_worker + (w < remainder);
150 if constexpr(nothrow_) {
151 run_task_range(w, start, length);
154 run_task_range(w, start, length);
156 errors[w] = std::current_exception();
163#undef SUBPAR_USES_OPENMP
164#undef SUBPAR_USES_OPENMP_RANGE
167 std::vector<std::thread> workers;
168 workers.reserve(sanisizer::cast<
decltype(workers.size())>(num_workers));
170 for (
int w = 0; w < num_workers; ++w) {
171 const Task_ length = tasks_per_worker + (w < remainder);
173 if constexpr(nothrow_) {
174 workers.emplace_back(run_task_range, w, start, length);
176 workers.emplace_back([&run_task_range,&errors](
int w, Task_ start, Task_ length) ->
void {
178 run_task_range(w, start, length);
180 errors[w] = std::current_exception();
182 }, w, start, length);
188 for (
auto& wrk : workers) {
193 if constexpr(!nothrow_) {
194 for (
const auto& e : errors) {
196 std::rethrow_exception(e);
void parallelize_range(int num_workers, const Task_ num_tasks, const Run_ run_task_range)
Parallelize a range of tasks across multiple workers.
Definition range.hpp:98