1 // -*- C++ -*-
2 // -*-===----------------------------------------------------------------------===//
3 //
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7 // See https://llvm.org/LICENSE.txt for license information.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #ifndef _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
12 #define _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
13
14 #include <cstddef>
15
16 #include "util.h"
17
18 namespace __pstl
19 {
20 namespace __omp_backend
21 {
22
23 template <class _Index, class _Fp>
24 void
__parallel_for_body(_Index __first,_Index __last,_Fp __f)25 __parallel_for_body(_Index __first, _Index __last, _Fp __f)
26 {
27 // initial partition of the iteration space into chunks
28 auto __policy = __omp_backend::__chunk_partitioner(__first, __last);
29
30 // To avoid over-subscription we use taskloop for the nested parallelism
31 _PSTL_PRAGMA(omp taskloop untied mergeable)
32 for (std::size_t __chunk = 0; __chunk < __policy.__n_chunks; ++__chunk)
33 {
34 __pstl::__omp_backend::__process_chunk(__policy, __first, __chunk, __f);
35 }
36 }
37
38 //------------------------------------------------------------------------
39 // Notation:
40 // Evaluation of brick f[i,j) for each subrange [i,j) of [first, last)
41 //------------------------------------------------------------------------
42
43 template <class _ExecutionPolicy, class _Index, class _Fp>
44 void
__parallel_for(__pstl::__internal::__openmp_backend_tag,_ExecutionPolicy &&,_Index __first,_Index __last,_Fp __f)45 __parallel_for(__pstl::__internal::__openmp_backend_tag, _ExecutionPolicy&&, _Index __first, _Index __last, _Fp __f)
46 {
47 if (omp_in_parallel())
48 {
49 // we don't create a nested parallel region in an existing parallel
50 // region: just create tasks
51 __pstl::__omp_backend::__parallel_for_body(__first, __last, __f);
52 }
53 else
54 {
55 // in any case (nested or non-nested) one parallel region is created and
56 // only one thread creates a set of tasks
57 _PSTL_PRAGMA(omp parallel)
58 _PSTL_PRAGMA(omp single nowait) { __pstl::__omp_backend::__parallel_for_body(__first, __last, __f); }
59 }
60 }
61
62 } // namespace __omp_backend
63 } // namespace __pstl
64 #endif // _PSTL_INTERNAL_OMP_PARALLEL_FOR_H
65