File indexing completed on 2025-01-18 09:28:02
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012
0013
0014 #ifdef ACTS_EXAMPLES_NO_TBB
0015 #define ACTS_EXAMPLES_WITH_TBB(a)
0016 #include <stdexcept>
0017 #else
0018 #define ACTS_EXAMPLES_WITH_TBB(a) a
0019 #include <optional>
0020
0021 #include <tbb/parallel_for.h>
0022 #include <tbb/queuing_mutex.h>
0023 #include <tbb/task_arena.h>
0024 #endif
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #ifdef ACTS_EXAMPLES_NO_TBB
0043 namespace ActsExamples::tbb {
0044 namespace task_arena {
0045 constexpr int automatic = -1;
0046 }
0047
0048 template <typename Value>
0049 struct blocked_range {
0050 blocked_range(Value begin_, Value end_) : my_end(end_), my_begin(begin_) {}
0051 Value begin() const { return my_begin; }
0052 Value end() const { return my_end; }
0053
0054 private:
0055 Value my_end;
0056 Value my_begin;
0057 };
0058 }
0059 #endif
0060
0061 namespace ActsExamples::tbbWrap {
0062
0063
0064
0065
0066
0067 static bool enableTBB(int nthreads = -99) {
0068 static bool setting = false;
0069 if (nthreads != -99) {
0070 #ifdef ACTS_EXAMPLES_NO_TBB
0071 if (nthreads > 1) {
0072 throw std::runtime_error(
0073 "tbb is not available, so can't do multi-threading.");
0074 }
0075 #else
0076 bool newSetting = (nthreads != 1);
0077 if (!setting && newSetting) {
0078 setting = newSetting;
0079 }
0080 #endif
0081 }
0082 return setting;
0083 }
0084
0085
0086
0087
0088
0089 class task_arena {
0090 #ifndef ACTS_EXAMPLES_NO_TBB
0091 std::optional<tbb::task_arena> tbb;
0092 #endif
0093
0094 public:
0095 task_arena(int nthreads = tbb::task_arena::automatic,
0096 unsigned ACTS_EXAMPLES_WITH_TBB(res) = 1) {
0097 if (enableTBB(nthreads)) {
0098 #ifndef ACTS_EXAMPLES_NO_TBB
0099 tbb.emplace(nthreads, res);
0100 #endif
0101 }
0102 }
0103
0104 template <typename F>
0105 void execute(const F& f) {
0106 #ifndef ACTS_EXAMPLES_NO_TBB
0107 if (tbb) {
0108 tbb->execute(f);
0109 } else
0110 #endif
0111 {
0112 f();
0113 }
0114 }
0115 };
0116
0117
0118 class parallel_for {
0119 public:
0120 template <typename R, typename F>
0121 parallel_for(const R& r, const F& f) {
0122 #ifndef ACTS_EXAMPLES_NO_TBB
0123 if (enableTBB()) {
0124 tbb::parallel_for(r, f);
0125 } else
0126 #endif
0127 {
0128 for (auto i = r.begin(); i != r.end(); ++i) {
0129 f(R(i, i + 1));
0130 }
0131 }
0132 }
0133 };
0134
0135
0136 class queuing_mutex {
0137 #ifndef ACTS_EXAMPLES_NO_TBB
0138 std::optional<tbb::queuing_mutex> tbb;
0139 #endif
0140
0141 public:
0142 queuing_mutex() {
0143 #ifndef ACTS_EXAMPLES_NO_TBB
0144 if (enableTBB()) {
0145 tbb.emplace();
0146 }
0147 #endif
0148 }
0149
0150 class scoped_lock {
0151 #ifndef ACTS_EXAMPLES_NO_TBB
0152 std::optional<tbb::queuing_mutex::scoped_lock> tbb;
0153 #endif
0154
0155 public:
0156 scoped_lock() {
0157 #ifndef ACTS_EXAMPLES_NO_TBB
0158 if (enableTBB()) {
0159 tbb.emplace();
0160 }
0161 #endif
0162 }
0163
0164 scoped_lock(queuing_mutex& ACTS_EXAMPLES_WITH_TBB(m)) {
0165 #ifndef ACTS_EXAMPLES_NO_TBB
0166 if (enableTBB()) {
0167 tbb.emplace(*m.tbb);
0168 }
0169 #endif
0170 }
0171 };
0172 };
0173
0174 }