20 #ifndef TLP_PARALLEL_TOOLS_H 21 #define TLP_PARALLEL_TOOLS_H 23 #include <tulip/tulipconf.h> 26 #ifndef TLP_NO_THREADS 34 typedef long long OMP_ITER_TYPE;
36 typedef size_t OMP_ITER_TYPE;
39 #define OMP(x) _Pragma(STRINGIFY(omp x)) 40 #define OMP_CRITICAL_SECTION(x) _Pragma(STRINGIFY(omp critical(x))) 42 #define OMP(x) __pragma(omp x) 43 #define OMP_CRITICAL_SECTION(x) __pragma(omp critical(x)) 70 static unsigned int maxNumberOfThreads;
72 #if !defined(TLP_NO_THREADS) && !defined(_OPENMP) 75 static void allocateThreadNumber();
78 static void freeThreadNumber();
82 template <
typename runFunction>
83 static inline std::thread *launchThread(
const runFunction &f, uint begin, uint end) {
84 auto thrdFunction = [&](uint begin, uint end) {
85 allocateThreadNumber();
89 return new std::thread(thrdFunction, begin, end);
95 #if !defined(TLP_NO_THREADS) && !defined(_OPENMP) 99 template <
typename runFunction>
100 static inline std::thread *launchThread(
const runFunction &f) {
101 auto thrdFunction = [&]() {
102 allocateThreadNumber();
106 return new std::thread(thrdFunction);
114 static unsigned int getNumberOfProcs();
119 static unsigned int getNumberOfThreads();
124 static void setNumberOfThreads(
unsigned int nbThreads);
129 static unsigned int getThreadNumber();
137 template <
typename ThreadFunction>
138 static inline void iterate(
size_t maxId,
const ThreadFunction &threadFunction) {
139 #ifndef TLP_NO_THREADS 144 size_t nbPerThread = maxId == 1 ? 1 : std::max(maxId / (maxNumberOfThreads - 1),
size_t(2));
146 size_t begin = 0, end = nbPerThread;
147 maxId -= end - begin;
149 std::vector<std::thread *> threads;
150 threads.reserve(maxNumberOfThreads - 1);
152 threads.push_back(launchThread(threadFunction, begin, end));
153 if (nbPerThread > 1) {
154 if (maxNumberOfThreads - threads.size() == maxId)
158 end += std::min(nbPerThread, maxId);
159 maxId -= end - begin;
162 threadFunction(begin, end);
164 for (
auto thrd : threads) {
169 threadFunction(0, maxId);
176 #ifndef TLP_NO_THREADS 178 #define TLP_MAX_NB_THREADS 128 180 #define TLP_NB_THREADS tlp::ThreadManager::getNumberOfThreads() 184 #define TLP_LOCK_SECTION(mtx) OMP_CRITICAL_SECTION(mtx) 185 #define TLP_UNLOCK_SECTION(mtx) 186 #define TLP_DECLARE_GLOBAL_LOCK(mtx) extern void mtx() 187 #define TLP_DEFINE_GLOBAL_LOCK(mtx) extern void mtx() 188 #define TLP_GLOBALLY_LOCK_SECTION(mtx) OMP_CRITICAL_SECTION(mtx) 189 #define TLP_GLOBALLY_UNLOCK_SECTION(mtx) 193 #define TLP_LOCK_SECTION(mtx) \ 194 static std::mutex mtx; \ 196 #define TLP_UNLOCK_SECTION(mtx) mtx.unlock() 197 #define TLP_DECLARE_GLOBAL_LOCK(mtx) extern std::mutex mtx 198 #define TLP_DEFINE_GLOBAL_LOCK(mtx) std::mutex mtx 199 #define TLP_GLOBALLY_LOCK_SECTION(mtx) mtx.lock(); 200 #define TLP_GLOBALLY_UNLOCK_SECTION(mtx) mtx.unlock() 207 #define TLP_MAX_NB_THREADS 1 209 #define TLP_NB_THREADS 1 211 #define TLP_LOCK_SECTION(mtx) 212 #define TLP_UNLOCK_SECTION(mtx) 213 #define TLP_DECLARE_GLOBAL_LOCK(mtx) extern void mtx() 214 #define TLP_DEFINE_GLOBAL_LOCK(mtx) extern void mtx() 215 #define TLP_GLOBALLY_LOCK_SECTION(mtx) 216 #define TLP_GLOBALLY_UNLOCK_SECTION(mtx) 247 template <
typename IdxFunction>
251 for (OMP_ITER_TYPE i = 0; i < OMP_ITER_TYPE(maxIdx); ++i) {
255 auto threadFunction = [&](
size_t begin,
size_t end) {
256 for (; begin < end; ++begin) {
264 template <
typename EltType,
typename IdxFunction>
265 void inline TLP_PARALLEL_MAP_VECTOR(
const std::vector<EltType> &vect,
266 const IdxFunction &idxFunction) {
268 auto maxIdx = vect.size();
270 for (OMP_ITER_TYPE i = 0; i < OMP_ITER_TYPE(maxIdx); ++i) {
271 idxFunction(vect[i]);
274 auto threadFunction = [&](
size_t begin,
size_t end) {
275 for (; begin < end; ++begin) {
276 idxFunction(vect[begin]);
284 template <
typename EltType,
typename IdxFunction>
285 void inline TLP_PARALLEL_MAP_VECTOR_AND_INDICES(
const std::vector<EltType> &vect,
286 const IdxFunction &idxFunction) {
288 auto maxIdx = vect.size();
290 for (OMP_ITER_TYPE i = 0; i < OMP_ITER_TYPE(maxIdx); ++i) {
291 idxFunction(vect[i], i);
294 auto threadFunction = [&](
size_t begin,
size_t end) {
295 for (; begin < end; ++begin) {
296 idxFunction(vect[begin], begin);
304 template <
typename F1,
typename F2>
305 void inline TLP_PARALLEL_SECTIONS(
const F1 &f1,
const F2 &f2) {
306 #ifndef TLP_NO_THREADS 309 OMP(sections nowait) {
319 auto thrd = ThreadManager::launchThread(f1);
330 template <
typename F1,
typename F2,
typename F3>
331 void inline TLP_PARALLEL_SECTIONS(
const F1 &f1,
const F2 &f2,
const F3 &f3) {
332 #ifndef TLP_NO_THREADS 335 OMP(sections nowait) {
348 auto thrd1 = ThreadManager::launchThread(f1);
349 auto thrd2 = ThreadManager::launchThread(f2);
363 template <
typename F1,
typename F2,
typename F3,
typename F4>
364 void inline TLP_PARALLEL_SECTIONS(
const F1 &f1,
const F2 &f2,
const F3 &f3,
const F4 &f4) {
365 #ifndef TLP_NO_THREADS 368 OMP(sections nowait) {
384 auto thrd1 = ThreadManager::launchThread(f1);
385 auto thrd2 = ThreadManager::launchThread(f2);
386 auto thrd3 = ThreadManager::launchThread(f3);
404 #endif // TLP_PARALLEL_TOOLS_H
static void iterate(size_t maxId, const ThreadFunction &threadFunction)
void TLP_PARALLEL_MAP_INDICES(size_t maxIdx, const IdxFunction &idxFunction)
Static wrapper class around the std::thread.