]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/parallel/omp_loop.h
re PR libstdc++/33893 ([parallel mode] Algorithms rely on omp_set_dynamic(false))
[thirdparty/gcc.git] / libstdc++-v3 / include / parallel / omp_loop.h
CommitLineData
c2ba9709
JS
1// -*- C++ -*-
2
3// Copyright (C) 2007 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library. This library is free
6// software; you can redistribute it and/or modify it under the terms
7// of the GNU General Public License as published by the Free Software
8// Foundation; either version 2, or (at your option) any later
9// version.
10
11// This library is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this library; see the file COPYING. If not, write to
18// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19// MA 02111-1307, USA.
20
21// As a special exception, you may use this file as part of a free
22// software library without restriction. Specifically, if other files
23// instantiate templates or use macros or inline functions from this
24// file, or you compile this file and link it with other files to
25// produce an executable, this file does not by itself cause the
26// resulting executable to be covered by the GNU General Public
27// License. This exception does not however invalidate any other
28// reasons why the executable file might be covered by the GNU General
29// Public License.
30
31/** @file parallel/omp_loop.h
32 * @brief Parallelization of embarrassingly parallel execution by
33 * means of an OpenMP for loop.
34 * This file is a GNU parallel extension to the Standard C++ Library.
35 */
36
37// Written by Felix Putze.
38
39#ifndef _GLIBCXX_PARALLEL_OMP_LOOP_H
40#define _GLIBCXX_PARALLEL_OMP_LOOP_H 1
41
42#include <omp.h>
43
44#include <parallel/settings.h>
45#include <parallel/basic_iterator.h>
e683ee2a 46#include <parallel/base.h>
c2ba9709
JS
47
48namespace __gnu_parallel
49{
e683ee2a
JS
50/** @brief Embarrassingly parallel algorithm for random access
51 * iterators, using an OpenMP for loop.
52 *
53 * @param begin Begin iterator of element sequence.
54 * @param end End iterator of element sequence.
55 * @param o User-supplied functor (comparator, predicate, adding
56 * functor, etc.).
57 * @param f Functor to "process" an element with op (depends on
58 * desired functionality, e. g. for std::for_each(), ...).
59 * @param r Functor to "add" a single result to the already
60 * processed elements (depends on functionality).
61 * @param base Base value for reduction.
62 * @param output Pointer to position where final result is written to
63 * @param bound Maximum number of elements processed (e. g. for
64 * std::count_n()).
65 * @return User-supplied functor (that may contain a part of the result).
66 */
67template<typename RandomAccessIterator,
68 typename Op,
69 typename Fu,
70 typename Red,
71 typename Result>
c2ba9709 72 Op
e683ee2a
JS
73 for_each_template_random_access_omp_loop(
74 RandomAccessIterator begin,
75 RandomAccessIterator end,
76 Op o, Fu& f, Red r, Result base, Result& output,
77 typename std::iterator_traits<RandomAccessIterator>::
78 difference_type bound)
c2ba9709 79 {
e683ee2a
JS
80 typedef typename
81 std::iterator_traits<RandomAccessIterator>::difference_type
82 difference_type;
c2ba9709 83
c2ba9709 84 difference_type length = end - begin;
e683ee2a
JS
85 thread_index_t num_threads =
86 __gnu_parallel::min<difference_type>(get_max_threads(), length);
c2ba9709 87
e683ee2a
JS
88 Result *thread_results;
89
90# pragma omp parallel num_threads(num_threads)
c2ba9709 91 {
e683ee2a
JS
92# pragma omp single
93 {
94 num_threads = omp_get_num_threads();
95 thread_results = new Result[num_threads];
96
97 for (thread_index_t i = 0; i < num_threads; i++)
98 thread_results[i] = Result();
99 }
100
101 thread_index_t iam = omp_get_thread_num();
102
103# pragma omp for schedule(dynamic, Settings::workstealing_chunk_size)
104 for (difference_type pos = 0; pos < length; pos++)
105 thread_results[iam] =
106 r(thread_results[iam], f(o, begin+pos));
107 } //parallel
c2ba9709
JS
108
109 for (thread_index_t i = 0; i < num_threads; i++)
e683ee2a 110 output = r(output, thread_results[i]);
c2ba9709
JS
111
112 delete [] thread_results;
113
114 // Points to last element processed (needed as return value for
115 // some algorithms like transform).
116 f.finish_iterator = begin + length;
117
118 return o;
119 }
e683ee2a 120
c2ba9709
JS
121} // end namespace
122
123#endif