FreeTensor
Loading...
Searching...
No Matches
omp_utils.h
Go to the documentation of this file.
1#ifndef FREE_TENSOR_OMP_UTILS_H
2#define FREE_TENSOR_OMP_UTILS_H
3
4#include <atomic>
5#include <concepts>
6#include <exception>
7#include <functional>
8
9#include <omp.h>
10
11namespace freetensor {
12
16template <std::integral T>
17void exceptSafeParallelFor(T begin, T end, T step,
18 const std::function<void(T)> &body,
19 omp_sched_t schedKind,
20 int schedChunkSize = 0 /* 0 = auto */) {
21 std::atomic_flag hasExcept_ = ATOMIC_FLAG_INIT;
22 // ATOMIC_FLAG_INIT is required before C++20, but deprecated since C++20.
23 // Keep it for now for potentially unsupported compilers
24
25 std::exception_ptr except_;
26
27 omp_set_schedule(schedKind, schedChunkSize);
28 // omp cancel requires separating `omp parallel` and `omp for`:
29 // https://stackoverflow.com/questions/30275513/gcc-5-1-warns-cancel-construct-within-parallel-for-construct
30#pragma omp parallel
31 {
32 // schedule(runtime) = read schedule set by omp_set_schedule
33#pragma omp for schedule(runtime)
34 for (auto i = begin; i < end; i += step) {
35 try {
36 body(i);
37 } catch (...) {
38 if (!hasExcept_.test_and_set()) {
39 except_ = std::current_exception();
40#pragma omp cancel for
41 }
42 }
43#pragma omp cancellation point for // Check wheter to cancel here
44 }
45 }
46 if (except_) {
47 std::rethrow_exception(except_);
48 }
49}
50
51} // namespace freetensor
52
53#endif // FREE_TENSOR_OMP_UTILS_H
Definition: allocator.h:9
void exceptSafeParallelFor(T begin, T end, T step, const std::function< void(T)> &body, omp_sched_t schedKind, int schedChunkSize=0)
Definition: omp_utils.h:17