BRE12
parallel_for.h
1 /*
2  Copyright 2005-2016 Intel Corporation. All Rights Reserved.
3 
4  This file is part of Threading Building Blocks. Threading Building Blocks is free software;
5  you can redistribute it and/or modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation. Threading Building Blocks is
7  distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9  See the GNU General Public License for more details. You should have received a copy of
10  the GNU General Public License along with Threading Building Blocks; if not, write to the
11  Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
12 
13  As a special exception, you may use this file as part of a free software library without
14  restriction. Specifically, if other files instantiate templates or use macros or inline
15  functions from this file, or you compile this file and link it with other files to produce
16  an executable, this file does not by itself cause the resulting executable to be covered
17  by the GNU General Public License. This exception does not however invalidate any other
18  reasons why the executable file might be covered by the GNU General Public License.
19 */
20 
21 #ifndef __TBB_SERIAL_parallel_for_H
22 #define __TBB_SERIAL_parallel_for_H
23 
24 #if !TBB_USE_EXCEPTIONS && _MSC_VER
25  // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
26  #pragma warning (push)
27  #pragma warning (disable: 4530)
28 #endif
29 
30 #include <stdexcept>
31 #include <string> // required to construct std exception classes
32 
33 #if !TBB_USE_EXCEPTIONS && _MSC_VER
34  #pragma warning (pop)
35 #endif
36 
37 #include "tbb_annotate.h"
38 
39 #ifndef __TBB_NORMAL_EXECUTION
40 #include "tbb/blocked_range.h"
41 #include "tbb/partitioner.h"
42 #endif
43 
44 namespace tbb {
45 namespace serial {
46 namespace interface9 {
47 
48 // parallel_for serial annotated implementation
49 
50 template< typename Range, typename Body, typename Partitioner >
51 class start_for : tbb::internal::no_copy {
52  Range my_range;
53  const Body my_body;
54  typename Partitioner::task_partition_type my_partition;
55  void execute();
56 
58  start_for( const Range& range, const Body& body, Partitioner& partitioner ) :
59  my_range( range ),
60  my_body( body ),
61  my_partition( partitioner )
62  {
63  }
64 
66 
67  start_for( start_for& parent_, typename Partitioner::split_type& split_obj ) :
68  my_range( parent_.my_range, split_obj ),
69  my_body( parent_.my_body ),
70  my_partition( parent_.my_partition, split_obj )
71  {
72  }
73 
74 public:
75  static void run( const Range& range, const Body& body, Partitioner& partitioner ) {
76  if( !range.empty() ) {
77  ANNOTATE_SITE_BEGIN( tbb_parallel_for );
78  {
79  start_for a( range, body, partitioner );
80  a.execute();
81  }
82  ANNOTATE_SITE_END( tbb_parallel_for );
83  }
84  }
85 };
86 
87 template< typename Range, typename Body, typename Partitioner >
89  if( !my_range.is_divisible() || !my_partition.is_divisible() ) {
90  ANNOTATE_TASK_BEGIN( tbb_parallel_for_range );
91  {
92  my_body( my_range );
93  }
94  ANNOTATE_TASK_END( tbb_parallel_for_range );
95  } else {
96  typename Partitioner::split_type split_obj;
97  start_for b( *this, split_obj );
98  this->execute(); // Execute the left interval first to keep the serial order.
99  b.execute(); // Execute the right interval then.
100  }
101 }
102 
104 
105 template<typename Range, typename Body>
106 void parallel_for( const Range& range, const Body& body ) {
108 }
109 
111 
112 template<typename Range, typename Body>
113 void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) {
115 }
116 
118 
119 template<typename Range, typename Body>
120 void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) {
122 }
123 
124 #if TBB_PREVIEW_STATIC_PARTITIONER
125 
127 template<typename Range, typename Body>
128 void parallel_for( const Range& range, const Body& body, const static_partitioner& partitioner ) {
130 }
131 #endif
132 
134 
135 template<typename Range, typename Body>
136 void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) {
138 }
139 
141 template <typename Index, typename Function, typename Partitioner>
142 void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& ) {
143  if (step <= 0 )
144  throw std::invalid_argument( "nonpositive_step" );
145  else if (last > first) {
146  // Above "else" avoids "potential divide by zero" warning on some platforms
147  ANNOTATE_SITE_BEGIN( tbb_parallel_for );
148  for( Index i = first; i < last; i = i + step ) {
149  ANNOTATE_TASK_BEGIN( tbb_parallel_for_iteration );
150  { f( i ); }
151  ANNOTATE_TASK_END( tbb_parallel_for_iteration );
152  }
153  ANNOTATE_SITE_END( tbb_parallel_for );
154  }
155 }
156 
158 template <typename Index, typename Function>
159 void parallel_for(Index first, Index last, Index step, const Function& f) {
160  parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, auto_partitioner());
161 }
163 template <typename Index, typename Function>
164 void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& p) {
165  parallel_for_impl<Index,Function,const simple_partitioner>(first, last, step, f, p);
166 }
168 template <typename Index, typename Function>
169 void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& p) {
170  parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, p);
171 }
172 #if TBB_PREVIEW_STATIC_PARTITIONER
173 template <typename Index, typename Function>
175 void parallel_for(Index first, Index last, Index step, const Function& f, const static_partitioner& p) {
176  parallel_for_impl<Index,Function,const static_partitioner>(first, last, step, f, p);
177 }
178 #endif
179 template <typename Index, typename Function>
181 void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& p) {
182  parallel_for_impl(first, last, step, f, p);
183 }
184 
186 template <typename Index, typename Function>
187 void parallel_for(Index first, Index last, const Function& f) {
188  parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, auto_partitioner());
189 }
191 template <typename Index, typename Function>
192 void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& p) {
193  parallel_for_impl<Index,Function,const simple_partitioner>(first, last, static_cast<Index>(1), f, p);
194 }
196 template <typename Index, typename Function>
197  void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& p) {
198  parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, p);
199 }
200 #if TBB_PREVIEW_STATIC_PARTITIONER
201 template <typename Index, typename Function>
203 void parallel_for(Index first, Index last, const Function& f, const static_partitioner& p) {
204  parallel_for_impl<Index,Function,const static_partitioner>(first, last, static_cast<Index>(1), f, p);
205 }
206 #endif
207 template <typename Index, typename Function>
209 void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& p) {
210  parallel_for_impl(first, last, static_cast<Index>(1), f, p);
211 }
212 
213 } // namespace interfaceX
214 
216 
217 } // namespace serial
218 
219 #ifndef __TBB_NORMAL_EXECUTION
221 #endif
222 
223 } // namespace tbb
224 
225 #endif /* __TBB_SERIAL_parallel_for_H */
Definition: parallel_for.h:51
void parallel_for(const Range &range, const Body &body)
Parallel iteration over range with default partitioner.
Definition: parallel_for.h:185
The namespace tbb contains all components of the library.
Definition: parallel_for.h:44
void parallel_for(const Range &range, const Body &body, affinity_partitioner &partitioner, task_group_context &context)
Parallel iteration over range with affinity_partitioner and user-supplied context.
Definition: parallel_for.h:253