PolyFEM
Loading...
Searching...
No Matches
MaybeParallelFor.tpp
Go to the documentation of this file.
1#include <polyfem/utils/MaybeParallelFor.hpp>
2
3#if defined(POLYFEM_WITH_TBB)
4#include <tbb/parallel_for.h>
5#include <tbb/parallel_reduce.h>
6#include <tbb/enumerable_thread_specific.h>
7#elif defined(POLYFEM_WITH_CPP_THREADS)
8#include <polyfem/utils/par_for.hpp>
9#include <execution>
10#else
11// Not using parallel for
12#endif
13
14namespace polyfem
15{
16 namespace utils
17 {
18 inline void maybe_parallel_for(int size, const std::function<void(int, int, int)> &partial_for)
19 {
20#if defined(POLYFEM_WITH_CPP_THREADS)
21 par_for(size, partial_for);
22#elif defined(POLYFEM_WITH_TBB)
23 if (get_n_threads() == 1)
24 partial_for(0, size, /*thread_id=*/0);
25 else
26 tbb::parallel_for(tbb::blocked_range<int>(0, size), [&](const tbb::blocked_range<int> &r) {
27 partial_for(r.begin(), r.end(), tbb::this_task_arena::current_thread_index());
28 });
29#else
30 partial_for(0, size, /*thread_id=*/0); // actually the full for loop
31#endif
32 }
33
34 inline void maybe_parallel_for(int size, const std::function<void(int)> &body)
35 {
36#if defined(POLYFEM_WITH_CPP_THREADS)
37 for (int i = 0; i < size; ++i)
38 body(i);
39#elif defined(POLYFEM_WITH_TBB)
40 if (get_n_threads() == 1)
41 {
42 for (int i = 0; i < size; ++i)
43 body(i);
44 }
45 else
46 tbb::parallel_for(0, size, body);
47#else
48 for (int i = 0; i < size; ++i)
49 body(i);
50#endif
51 }
52
53 template <typename LocalStorage>
54 inline auto create_thread_storage(const LocalStorage &initial_local_storage)
55 {
56#if defined(POLYFEM_WITH_CPP_THREADS)
57 return std::vector<LocalStorage>(get_n_threads(), initial_local_storage);
58#elif defined(POLYFEM_WITH_TBB)
59 return tbb::enumerable_thread_specific<LocalStorage>(initial_local_storage);
60#else
61 return std::array<LocalStorage, 1>{{initial_local_storage}};
62#endif
63 }
64
65 template <typename Storages>
66 inline auto &get_local_thread_storage(Storages &storage, int thread_id)
67 {
68#if defined(POLYFEM_WITH_CPP_THREADS)
69 return storage[thread_id];
70#elif defined(POLYFEM_WITH_TBB)
71 return storage.local();
72#else
73 assert(thread_id == 0);
74 assert(storage.size() == 1);
75 return storage[0];
76#endif
77 }
78 } // namespace utils
79} // namespace polyfem