OpenWalnut  1.5.0dev
WThreadedJobs.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WTHREADEDJOBS_H
26 #define WTHREADEDJOBS_H
27 
28 #include <memory>
29 #include <string>
30 
31 
32 #include "WException.h"
33 #include "WFlag.h"
34 
35 /**
36  * \class WThreadedJobs
37  *
38  * A threaded functor base class for producer-consumer-style multithreaded computation.
39  *
40  * A job generator function produces jobs that are then distributed to the threads in
41  * a first come first serve manner. The first template parameter is the type of the input data,
42  * for example a WDataSetScalar. The second template parameter is the type of object that
43  * represents the jobs.
44  *
45  * Both the getJob() and the compute() functions need to be implemented.
46  *
47  * \ingroup common
48  */
49 template< class Input_T, class Job_T >
51 {
52 public:
53  //! the input type
54  typedef Input_T InputType;
55 
56  //! the job type
57  typedef Job_T JobType;
58 
59  /**
60  * Constructor.
61  *
62  * \param input The input.
63  */
64  WThreadedJobs( std::shared_ptr< InputType const > input ); // NOLINT
65 
66  /**
67  * Destructor.
68  */
69  virtual ~WThreadedJobs();
70 
71  /**
72  * The threaded function operation. Pulls jobs and executes the \see compute()
73  * function.
74  *
75  * \param id The thread's ID.
76  * \param numThreads How many threads are working on the jobs.
77  * \param shutdown A shared flag indicating the thread should be stopped.
78  */
79  void operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown );
80 
81  /**
82  * Abstract function for the job aquisition.
83  *
84  * \param job The job (output).
85  * \return false, iff no more jobs need to be processed.
86  */
87  virtual bool getJob( JobType& job ) = 0; // NOLINT
88 
89  /**
90  * Abstract function that performs the actual computation per job.
91  *
92  * \param input The input data.
93  * \param job The current job.
94  */
95  virtual void compute( std::shared_ptr< InputType const > input, JobType const& job ) = 0;
96 
97 protected:
98  //! the input
99  std::shared_ptr< InputType const > m_input;
100 private:
101 };
102 
103 template< class Input_T, class Job_T >
104 WThreadedJobs< Input_T, Job_T >::WThreadedJobs( std::shared_ptr< InputType const > input )
105  : m_input( input )
106 {
107  if( !m_input )
108  {
109  throw WException( std::string( "Invalid input." ) );
110  }
111 }
112 
113 template< class Input_T, class Job_T >
115 {
116 }
117 
118 template< class Input_T, class Job_T >
119 void WThreadedJobs< Input_T, Job_T >::operator() ( std::size_t /* id */, std::size_t /* numThreads */, WBoolFlag const& shutdown )
120 {
121  JobType job;
122  while( getJob( job ) && !shutdown() )
123  {
124  compute( m_input, job );
125  }
126 }
127 
128 /**
129  * Nearly the same class as WThreadedJobs, but this class is intended to be used for multithreaded operations on voxels and therefore it
130  * uses Striping to partition the data. This is necessarry since if the threads are not operating on blocks, they slow down!
131  */
132 template< class Input_T, class Job_T >
134 {
135 public:
136  //! the input type
137  typedef Input_T InputType;
138 
139  //! the job type
140  typedef Job_T JobType;
141 
142  /**
143  * Constructor.
144  *
145  * \param input The input.
146  */
147  WThreadedStripingJobs( std::shared_ptr< InputType const > input ); // NOLINT
148 
149  /**
150  * Destructor.
151  */
153 
154  /**
155  * The threaded function operation. Pulls jobs and executes the \see compute()
156  * function.
157  *
158  * \param id The thread's ID.
159  * \param numThreads How many threads are working on the jobs.
160  * \param shutdown A shared flag indicating the thread should be stopped.
161  */
162  void operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown );
163 
164  /**
165  * Abstract function that performs the actual computation per voxel.
166  *
167  * \param input The input data.
168  * \param voxelNum The voxel number to operate on.
169  */
170  virtual void compute( std::shared_ptr< InputType const > input, std::size_t voxelNum ) = 0;
171 
172 protected:
173  //! the input
174  std::shared_ptr< InputType const > m_input;
175 private:
176 };
177 
178 template< class Input_T, class Job_T >
179 WThreadedStripingJobs< Input_T, Job_T >::WThreadedStripingJobs( std::shared_ptr< InputType const > input )
180  : m_input( input )
181 {
182  if( !m_input )
183  {
184  throw WException( std::string( "Invalid input." ) );
185  }
186 }
187 
188 template< class Input_T, class Job_T >
190 {
191 }
192 
193 template< class Input_T, class Job_T >
194 void WThreadedStripingJobs< Input_T, Job_T >::operator() ( std::size_t id, std::size_t numThreads, WBoolFlag const& shutdown )
195 {
196  WAssert( m_input, "Bug: operations of an invalid input requested." );
197  size_t numElements = m_input->size();
198 
199  // partition the voxels via simple striping
200  size_t start = numElements / numThreads * id;
201  size_t end = ( id + 1 ) * ( numElements / numThreads );
202  if( id == numThreads - 1 ) // last thread may have less elements to take care.
203  {
204  end = numElements;
205  }
206 
207  for( size_t voxelNum = start; ( voxelNum < end ) && !shutdown(); ++voxelNum )
208  {
209  compute( m_input, voxelNum );
210  }
211 }
212 
213 #endif // WTHREADEDJOBS_H
Basic exception handler.
Definition: WException.h:39
A threaded functor base class for producer-consumer-style multithreaded computation.
Definition: WThreadedJobs.h:51
std::shared_ptr< InputType const > m_input
the input
Definition: WThreadedJobs.h:99
virtual ~WThreadedJobs()
Destructor.
void operator()(std::size_t id, std::size_t numThreads, WBoolFlag const &shutdown)
The threaded function operation.
WThreadedJobs(std::shared_ptr< InputType const > input)
Constructor.
virtual bool getJob(JobType &job)=0
Abstract function for the job aquisition.
virtual void compute(std::shared_ptr< InputType const > input, JobType const &job)=0
Abstract function that performs the actual computation per job.
Input_T InputType
the input type
Definition: WThreadedJobs.h:54
Job_T JobType
the job type
Definition: WThreadedJobs.h:57
Nearly the same class as WThreadedJobs, but this class is intended to be used for multithreaded opera...
WThreadedStripingJobs(std::shared_ptr< InputType const > input)
Constructor.
void operator()(std::size_t id, std::size_t numThreads, WBoolFlag const &shutdown)
The threaded function operation.
std::shared_ptr< InputType const > m_input
the input
Input_T InputType
the input type
virtual ~WThreadedStripingJobs()
Destructor.
Job_T JobType
the job type
virtual void compute(std::shared_ptr< InputType const > input, std::size_t voxelNum)=0
Abstract function that performs the actual computation per voxel.