Bridge++  Version 1.5.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
threadManager_OpenMP.cpp
Go to the documentation of this file.
1 
15 
16 #include <omp.h>
17 
19 #include "IO/bridgeIO.h"
20 using Bridge::vout;
21 
22 namespace ThreadManager_OpenMP_Reduce{
23 
24 template<typename REALTYPE>
25 void sum_global(REALTYPE *a,
26  const int num,
27  std::vector<REALTYPE> &array_reduction,
28  const int each_buf_size,
29  const int i_thread, const int Nthread)
30 {
31  typedef REALTYPE real_t;
32  int remaining=num;
33  std::vector<real_t> sum;
34  real_t *psum=nullptr;
35 #pragma omp master
36  {
37  sum.resize(num);
38  for(int i=0; i<num; i++){
39  sum[i]=0;
40  }
41  psum=&sum[0];
42  }
43  real_t *pa=a;
44  while(remaining>0){ // sum over threads; shared buffer size is each_buf_Size
45  const int n=(remaining<each_buf_size)?num:each_buf_size;
46  for(int i=0; i<n; i++){
47  array_reduction[i_thread*each_buf_size+i] = pa[i];
48  }
49 #pragma omp barrier
50 #pragma omp master
51  {
52  for (int i = 0; i < Nthread; i++){
53  for(int j=0; j<n; j++){
54  psum[j] += array_reduction[i*each_buf_size+j];
55  }
56  }
57  psum+=each_buf_size;
58  } // master
59  pa+=each_buf_size;
60  remaining-=each_buf_size;
61 #pragma omp barrier
62  } // sum over threads, done
63 
64 #pragma omp master
65  {
66  Communicator::reduce_sum(num, a, &sum[0], 0);
67  } // a in the master threads knows the global sum
68 
69  remaining=num;
70  pa=a;
71  const int total_buf_size=each_buf_size*Nthread;
72  while(remaining>0){ // distributes the sum to each thread
73  const int n=(remaining<total_buf_size)?num:total_buf_size;
74 #pragma omp master
75  {
76  for(int i=0; i<n; i++){ // copy to the common buffer
77  array_reduction[i] = pa[i];
78  }
79  } // master
80 
81  // ensures to read updated m_darray_reduction
82 #pragma omp barrier
83  //#ifdef NECSX
84  //#pragma omp flush
85  //#else
86  //if(sizeof(real_t)==4){
87  //#pragma omp flush (ThreadManager_OpenMP::m_darray_reductionF)
88  // } else {
89  //#pragma omp flush (ThreadManager_OpenMP::m_darray_reduction)
90  // }
91  //#endif
92  for(int i=0; i<n; i++){ // copy from the common buffer
93  pa[i]=array_reduction[i];
94  }
95  pa+=total_buf_size;
96  remaining-=total_buf_size;
97 #pragma omp barrier
98  } // distributes the sum to each thread, done
99 }
100 
101 } // ThreadManager_OpenMP_Reduce
102 
103 //====================================================================
104 // initialization of static member variables.
105 
108 std::vector<double> ThreadManager_OpenMP::m_darray_reduction(0);
109 std::vector<float> ThreadManager_OpenMP::m_darray_reductionF(0);
110 
111 const std::string ThreadManager_OpenMP::class_name = "ThreadManager_OpenMP";
112 
113 //====================================================================
114 void ThreadManager_OpenMP::init(int Nthread)
115 {
117 
118  vout.general(m_vl, "%s: initialization\n", class_name.c_str());
119 
120  int Nthread_env = 0;
121 
122 #pragma omp parallel
123  {
124  if (omp_get_thread_num() == 0) {
125  Nthread_env = omp_get_num_threads();
126  }
127  }
128 
129 
130  if ((Nthread == Nthread_env) || (Nthread == 0)) {
131  m_Nthread = Nthread_env;
132  } else {
133  vout.general(m_vl, " Number of threads(env) = %d\n", Nthread_env);
134  vout.general(m_vl, " Number of threads(input) = %d\n", Nthread);
135  vout.general(m_vl, " resetting Number of threads.\n");
136  omp_set_num_threads(Nthread);
137  m_Nthread = Nthread;
138  }
139 
140  vout.general(m_vl, " Number of thread = %d\n", m_Nthread);
141 
144 }
145 
146 
147 //====================================================================
149 {
150  vout.paranoiac(m_vl, "%s: finalize.\n", class_name.c_str());
151 }
152 
153 
154 //====================================================================
156 {
157  return omp_get_num_threads();
158 }
159 
160 
161 //====================================================================
163 {
164  return omp_get_thread_num();
165 }
166 
167 
168 //====================================================================
170 {
171  int Nthread = get_num_threads();
172 
173  barrier(Nthread);
174 }
175 
176 
177 //====================================================================
179 {
180 #pragma omp barrier
181 }
182 
183 
184 //====================================================================
186 {
187 #pragma omp barrier
188 #pragma omp master
189  {
191  }
192 #pragma omp barrier
193 }
194 
195 
196 //====================================================================
198  const int i_thread, const int Nthread)
199 {
202  i_thread, Nthread);
203 }
204 
205 //====================================================================
207  const int num,
208  const int i_thread, const int Nthread)
209 {
212  i_thread, Nthread);
213 }
214 
215 
216 //====================================================================
218  const int i_thread, const int Nthread)
219 {
222  i_thread, Nthread);
223 }
224 
225 
226 //====================================================================
228  const int num,
229  const int i_thread, const int Nthread)
230 {
233  i_thread, Nthread);
234 }
235 
236 
237 //====================================================================
238 void ThreadManager_OpenMP::assert_single_thread(const std::string& name)
239 {
240  int Nthread = get_num_threads();
241 
242  if (Nthread != 1) {
243  vout.crucial(m_vl, "\n");
244  vout.crucial(m_vl, "##### Caution #####\n");
245  vout.crucial(m_vl, "Single-thread %s is called in parallel region.\n", name.c_str());
246  vout.crucial(m_vl, "Current number of thread = %d.\n", Nthread);
247 
248  exit(EXIT_FAILURE);
249  }
250 }
251 
252 
253 //====================================================================
254 //============================================================END=====
static int m_Nthread
number of threads.
static const int each_buf_size
reduction buffer size for each thread (double)
BridgeIO vout
Definition: bridgeIO.cpp:503
static int get_num_threads()
returns available number of threads.
void general(const char *format,...)
Definition: bridgeIO.cpp:197
static std::vector< float > m_darray_reductionF
static Bridge::VerboseLevel Vlevel()
static void wait()
barrier among threads inside a node.
static int get_thread_id()
returns thread id.
static void init(int Nthread)
setup: called in main only once.
static const std::string class_name
static void barrier(const int Nthread)
barrier among threads inside a node.
static void reduce_sum_global(double &value, const int i_thread, const int Nthread)
global reduction with summation: value is assumed thread local.
static void sync_barrier_all()
barrier among all the threads and nodes.
static void finalize()
finalization.
void paranoiac(const char *format,...)
Definition: bridgeIO.cpp:235
static const int each_buf_sizeF
reduction buffer size for each thread (float)
void crucial(const char *format,...)
Definition: bridgeIO.cpp:178
static Bridge::VerboseLevel m_vl
verbose level.
void sum_global(REALTYPE *a, const int num, std::vector< REALTYPE > &array_reduction, const int each_buf_size, const int i_thread, const int Nthread)
static std::vector< double > m_darray_reduction
VerboseLevel
Definition: bridgeIO.h:42
static int reduce_sum(int count, double *recv_buf, double *send_buf, int pattern=0)
make a global sum of an array of double over the communicator. pattern specifies the dimensions to be...
static int sync()
synchronize within small world.
static void assert_single_thread(const std::string &class_name)
assert currently running on single thread.