Shiokaze Framework
A research-oriented fluid solver for computer graphics
parallel_driver.h
Go to the documentation of this file.
1 /*
2 ** parallel_driver.h
3 **
4 ** This is part of Shiokaze, a research-oriented fluid solver for computer graphics.
5 ** Created by Ryoichi Ando <rand@nii.ac.jp> on Feb 1, 2018.
6 **
7 ** Permission is hereby granted, free of charge, to any person obtaining a copy of
8 ** this software and associated documentation files (the "Software"), to deal in
9 ** the Software without restriction, including without limitation the rights to use,
10 ** copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
11 ** Software, and to permit persons to whom the Software is furnished to do so,
12 ** subject to the following conditions:
13 **
14 ** The above copyright notice and this permission notice shall be included in all copies
15 ** or substantial portions of the Software.
16 **
17 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18 ** INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
19 ** PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 ** HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
21 ** CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 ** OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24 //
25 #ifndef SHKZ_PARALLEL_DRIVER_H
26 #define SHKZ_PARALLEL_DRIVER_H
27 //
28 #include <algorithm>
29 #include <vector>
30 #include <shiokaze/core/credit.h>
32 #include <shiokaze/math/shape.h>
33 #include "parallel_core.h"
34 #include "loop_splitter.h"
35 //
37 //
38 #define shkz_default_parallel_name "stdthread"
39 #define shkz_default_splitter_name "sequential_splitter"
40 //
42 class parallel_driver : public configurable, public credit {
45 public:
46  //
47  LONG_NAME("Parallel Driver")
48  ARGUMENT_NAME("Parallel")
59  parallel_driver ( recursive_configurable *parent, std::string parallel_name=shkz_default_parallel_name, std::string splitter_name=shkz_default_splitter_name ) : m_parallel_name(parallel_name), m_splitter_name(splitter_name) {
60  if( parent ) parent->add_child(this);
61  else setup_now();
62  }
71  parallel_driver ( std::string parallel_name=shkz_default_parallel_name, std::string splitter_name=shkz_default_splitter_name ) : parallel_driver(nullptr,parallel_name,splitter_name) {
72  setup_now();
73  }
80  int get_thread_num() const {
81  return m_maximal_threads;
82  }
89  void set_thread_num( int maximal_threads ) {
90  m_maximal_threads = maximal_threads;
91  }
98  const parallel_core *get() const {
99  return m_parallel_dispatcher.get();
100  }
107  void run( const std::vector<std::function<void()> > &functions ) {
108  if( m_maximal_threads > 1 ) {
109  m_parallel_dispatcher->run(functions);
110  } else {
111  for( auto f : functions ) f();
112  }
113  }
122  void for_each_byte_safe( size_t size, std::function<void(size_t n, int thread_index)> func ) const {
123  size_t size_div_8 = (size+7) / 8;
124  for_each( size_div_8, [&]( size_t n_div_8, int thread_index ) {
125  for( char i=0; i<8; ++i ) {
126  size_t n = 8*n_div_8+i;
127  if( n < size ) {
128  func(n,thread_index);
129  }
130  }
131  });
132  }
141  void for_each( size_t size, std::function<void(size_t n, int thread_index)> func ) const {
142  //
143  if( size ) {
144  int num_threads = m_maximal_threads;
145  if( num_threads > size ) num_threads = size;
146  if( num_threads > 1 ) {
147  //
148  assert(m_loop_splitter.get());
149  //
150  const void *context = m_loop_splitter->new_context(size,num_threads);
151  auto start_func = m_loop_splitter->get_start_func(context);
152  auto advance_func = m_loop_splitter->get_advance_func(context);
153  //
154  m_parallel_dispatcher->for_each(func,
155  [&](int q) { return start_func(context,q); },
156  [&](size_t &n, int q){ return advance_func(context,n,q); },
157  num_threads);
158  //
159  m_loop_splitter->delete_context(context);
160  } else {
161  for( size_t n=0; n<size; ++n ) {
162  func(n,0);
163  }
164  }
165  }
166  }
175  void for_each( size_t size, std::function<void(size_t n)> func ) const {
176  for_each(size,[&]( size_t n, int thread_n ) {
177  func(n);
178  });
179  }
190  void for_each( const shape2 &shape, std::function<void(int i, int j, int thread_index)> func ) const {
191  for_each(shape.count(),[&]( size_t n, int thread_index ) {
192  vec2i pi = shape.decode(n);
193  func(pi[0],pi[1],thread_index);
194  });
195  }
204  void for_each( const shape2 &shape, std::function<void(int i, int j)> func ) const {
205  for_each(shape,[&]( int i, int j, int thread_index ) {
206  func(i,j);
207  });
208  }
217  void for_each( const shape3 &shape, std::function<void(int i, int j, int k, int thread_index)> func ) const {
218  for_each(shape.count(),[&]( size_t n, int thread_index ) {
219  vec3i pi = shape.decode(n);
220  func(pi[0],pi[1],pi[2],thread_index);
221  });
222  }
231  void for_each( const shape3 &shape, std::function<void(int i, int j, int k)> func ) const {
232  for_each(shape,[&]( int i, int j, int k, int thread_index ) {
233  func(i,j,k);
234  });
235  }
236  //
237 private:
238  //
239  std::string m_parallel_name, m_splitter_name;
240  parallel_ptr m_parallel_dispatcher;
241  loop_splitter_ptr m_loop_splitter;
242  int m_maximal_threads {NUM_THREAD};
243  //
244  virtual void load( configuration &config ) override {
245  configuration::auto_group group(config,*this);
246  m_parallel_dispatcher = parallel_core::quick_load_module(config,m_parallel_name);
247  m_loop_splitter = loop_splitter::quick_load_module(config,m_splitter_name);
248  }
249  //
250  virtual void configure( configuration &config ) override {
251  configuration::auto_group group(config,*this);
252  config.get_integer("Threads",m_maximal_threads,"Number of maximal threads");
253  m_parallel_dispatcher->recursive_configure(config);
254  m_loop_splitter->recursive_configure(config);
255  }
256 };
257 //
259 //
260 #endif
261 //
shape.h
loop_splitter.h
parallel_driver
Class that facilitates the use of parallel_core class for parallel loop.
Definition: parallel_driver.h:44
parallel_driver::for_each
void for_each(const shape2 &shape, std::function< void(int i, int j)> func) const
Perform a two dimensional parallel loop operation.
Definition: parallel_driver.h:204
configurable::setup_now
virtual void setup_now(configuration &config=get_global_configuration())
Run load - configure - initialize processes.
Definition: configurable.h:95
configuration::get_integer
bool get_integer(std::string name, int &value, std::string description=std::string())
Get the integer parameter.
shape3::count
size_t count() const
Count the number of cells of the grid of this shape.
Definition: shape.h:857
credit.h
shape3
Structure that defines a three dimensional shape such as width, height and depth.
Definition: shape.h:478
ARGUMENT_NAME
#define ARGUMENT_NAME(argument_name)
Macro that defines the argument name.
Definition: credit.h:40
shape2::count
size_t count() const
Count the number of cells of the grid of this shape.
Definition: shape.h:385
configurable
Class for managing the workflow of load - configure - initialize.
Definition: configurable.h:40
parallel_driver::get
const parallel_core * get() const
Get a pointer to the internal instance of parallel_core.
Definition: parallel_driver.h:98
parallel_core
Abstract class that handles parallel operations. Used with loop_splitter. "stdthread" and "tbbthread"...
Definition: parallel_core.h:40
parallel_core.h
parallel_driver::for_each
void for_each(size_t size, std::function< void(size_t n)> func) const
Perform a parallel loop operation.
Definition: parallel_driver.h:175
parallel_driver::get_thread_num
int get_thread_num() const
Get the number of maximal threads set.
Definition: parallel_driver.h:80
SHKZ_BEGIN_NAMESPACE
#define SHKZ_BEGIN_NAMESPACE
Name space beggining definition for shiokaze.
Definition: common.h:39
parallel_driver::run
void run(const std::vector< std::function< void()> > &functions)
Run operations in parallel.
Definition: parallel_driver.h:107
parallel_driver::set_thread_num
void set_thread_num(int maximal_threads)
Set the number of maximal threads set.
Definition: parallel_driver.h:89
LONG_NAME
#define LONG_NAME(long_name)
Macro that defines the full name.
Definition: credit.h:37
parallel_driver::for_each
void for_each(const shape3 &shape, std::function< void(int i, int j, int k, int thread_index)> func) const
Perform a three dimensional parallel loop operation.
Definition: parallel_driver.h:217
recursive_configurable
Extended configurable class that holds multiple children of configurable.
Definition: configurable.h:126
configuration::auto_group
Class that automates the push and pop groups.
Definition: configuration.h:107
parallel_driver::for_each_byte_safe
void for_each_byte_safe(size_t size, std::function< void(size_t n, int thread_index)> func) const
Perform a parallel loop operation. Thread is guaranteed the same if (n mod 8) is the same.
Definition: parallel_driver.h:122
credit
Class that defines the name, argument name, author's name, email address, date and the version of the...
Definition: credit.h:47
configurable.h
configuration
Class that controls the settings of the program.
Definition: configuration.h:39
parallel_driver::for_each
void for_each(const shape2 &shape, std::function< void(int i, int j, int thread_index)> func) const
Perform a two dimensional parallel loop operation.
Definition: parallel_driver.h:190
shape2
Structure that defines shape such as width, height.
Definition: shape.h:42
SHKZ_END_NAMESPACE
#define SHKZ_END_NAMESPACE
Name space end definition for shiokaze.
Definition: common.h:44
parallel_driver::for_each
void for_each(size_t size, std::function< void(size_t n, int thread_index)> func) const
Perform a parallel loop operation.
Definition: parallel_driver.h:141
parallel_driver::parallel_driver
parallel_driver(std::string parallel_name=shkz_default_parallel_name, std::string splitter_name=shkz_default_splitter_name)
Constructor for parallel_driver.
Definition: parallel_driver.h:71
parallel_driver::for_each
void for_each(const shape3 &shape, std::function< void(int i, int j, int k)> func) const
Perform a three dimensional parallel loop operation.
Definition: parallel_driver.h:231