subpar
Substitutable parallelization for C++ libraries
Loading...
Searching...
No Matches
simple.hpp
Go to the documentation of this file.
1#ifndef SUBPAR_SIMPLE_HPP
2#define SUBPAR_SIMPLE_HPP
3
4#include "range.hpp"
5
6#ifndef SUBPAR_CUSTOM_PARALLELIZE_SIMPLE
7#include <vector>
8#include <stdexcept>
9#include <thread>
10#include <type_traits>
11#endif
12
18namespace subpar {
19
52template<bool nothrow_ = false, typename Task_, class Run_>
53void parallelize_simple(Task_ num_tasks, Run_ run_task) {
54#ifdef SUBPAR_CUSTOM_PARALLELIZE_SIMPLE
55 if constexpr(nothrow_) {
56#ifdef SUBPAR_CUSTOM_PARALLELIZE_SIMPLE_NOTHROW
57 SUBPAR_CUSTOM_PARALLELIZE_SIMPLE_NOTHROW(num_tasks, run_task);
58#else
59 SUBPAR_CUSTOM_PARALLELIZE_SIMPLE(num_tasks, run_task);
60#endif
61 } else {
62 SUBPAR_CUSTOM_PARALLELIZE_SIMPLE(num_tasks, run_task);
63 }
64
65#else
66 if (num_tasks == 0) {
67 return;
68 } else if (num_tasks == 1) {
69 run_task(0);
70 return;
71 }
72
73 auto errors = internal::create_error_vector<nothrow_>(num_tasks);
74
75#if defined(_OPENMP) && !defined(SUBPAR_NO_OPENMP_SIMPLE)
76#define SUBPAR_USES_OPENMP_SIMPLE 1
77
78 // OpenMP doesn't guarantee that we'll actually start 'num_tasks' workers,
79 // so we need to do a loop here to ensure that each task simple is executed.
80 #pragma omp parallel for num_threads(num_tasks)
81 for (Task_ w = 0; w < num_tasks; ++w) {
82 if constexpr(nothrow_) {
83 run_task(w);
84 } else {
85 try {
86 run_task(w);
87 } catch (...) {
88 errors[w] = std::current_exception();
89 }
90 }
91 }
92
93#else
94// Wiping it out, just in case.
95#undef SUBPAR_USES_OPENMP_SIMPLE
96
97 std::vector<std::thread> workers;
98 workers.reserve(num_tasks);
99
100 for (Task_ w = 0; w < num_tasks; ++w) {
101 if constexpr(nothrow_) {
102 workers.emplace_back(run_task, w);
103 } else {
104 workers.emplace_back([&run_task,&errors](int w) -> void {
105 try {
106 run_task(w);
107 } catch (...) {
108 errors[w] = std::current_exception();
109 }
110 }, w);
111 }
112 }
113
114 for (auto& wrk : workers) {
115 wrk.join();
116 }
117#endif
118
119 if constexpr(!nothrow_) {
120 for (const auto& e : errors) {
121 if (e) {
122 std::rethrow_exception(e);
123 }
124 }
125 }
126#endif
127}
128
129}
130
131#endif
Substitutable parallelization functions.
void parallelize_simple(Task_ num_tasks, Run_ run_task)
Parallelize individual tasks across workers.
Definition simple.hpp:53
Parallelize across a range of tasks.