COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-parallel-collective-all_reduce.hpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2013 von Karman Institute for Fluid Dynamics, Belgium
2 //
3 // This software is distributed under the terms of the
4 // GNU Lesser General Public License version 3 (LGPLv3).
5 // See doc/lgpl.txt and doc/gpl.txt for the license text.
6 
7 // this file is en-block included into utest-parallel-collective.cpp
8 // do not include anything here, rather in utest-parallel-collective.cpp
9 
11 
13 {
16  {
17  // rank and proc
18  nproc=PE::Comm::instance().size();
19  irank=PE::Comm::instance().rank();
20 
21  // ptr helpers
22  sndcnt=0;
23  ptr_snddat=new double[2*nproc];
24  ptr_rcvdat=new double[2*nproc];
25  ptr_tmprcv=new double[2*nproc];
26  ptr_sndmap=new int[nproc];
27  ptr_rcvmap=new int[nproc];
28  ptr_snddat2=new double[4*nproc];
29  ptr_rcvdat2=new double[4*nproc];
30  ptr_tmprcv2=new double[4*nproc];
31 
32  // std::Vector helpers
33  vec_snddat.resize(2*nproc);
34  vec_rcvdat.resize(2*nproc);
35  vec_tmprcv.resize(2*nproc);
36  vec_sndmap.resize(nproc);
37  vec_rcvmap.resize(nproc);
38  vec_snddat2.resize(4*nproc);
39  vec_rcvdat2.resize(4*nproc);
40  vec_tmprcv2.resize(4*nproc);
41  }
42 
45  {
46  delete[] ptr_snddat;
47  delete[] ptr_rcvdat;
48  delete[] ptr_sndmap;
49  delete[] ptr_rcvmap;
50  delete[] ptr_tmprcv;
51  delete[] ptr_snddat2;
52  delete[] ptr_rcvdat2;
53  delete[] ptr_tmprcv2;
54  }
55 
57  int nproc;
59  int irank;
60 
62  int sndcnt;
63  double* ptr_snddat;
64  double* ptr_rcvdat;
65  double* ptr_tmprcv;
66  int* ptr_sndmap;
67  int* ptr_rcvmap;
68  double* ptr_snddat2;
69  double* ptr_rcvdat2;
70  double* ptr_tmprcv2;
71 
73  std::vector<double> vec_snddat;
74  std::vector<double> vec_rcvdat;
75  std::vector<double> vec_tmprcv;
76  std::vector<int> vec_sndmap;
77  std::vector<int> vec_rcvmap;
78  std::vector<double> vec_snddat2;
79  std::vector<double> vec_rcvdat2;
80  std::vector<double> vec_tmprcv2;
81 
84  {
85  int i,j,k;
86  for (i=0; i<2*nproc; i++)
87  {
88  ptr_snddat[i]=(irank+1)*10000+(i+1);
89  ptr_rcvdat[i]=0.;
90  for (k=0; k<nproc; k++) ptr_rcvdat[i]+=(k+1)*10000+(i+1);
91  }
92  for (i=0; i<2*nproc; i++) { ptr_snddat2[2*i+0]=ptr_snddat[i]; ptr_snddat2[2*i+1]=ptr_snddat[i]+1; }
93  for (i=0; i<2*nproc; i++) { ptr_rcvdat2[2*i+0]=ptr_rcvdat[i]; ptr_rcvdat2[2*i+1]=ptr_rcvdat[i]+nproc; }
94  sndcnt=2*nproc;
95  vec_snddat.assign(ptr_snddat,ptr_snddat+2*nproc);
96  vec_rcvdat.assign(ptr_rcvdat,ptr_rcvdat+2*nproc);
97  vec_snddat2.assign(ptr_snddat2,ptr_snddat2+4*nproc);
98  vec_rcvdat2.assign(ptr_rcvdat2,ptr_rcvdat2+4*nproc);
99  }
100 
103  {
104  int i,j,k;
105  for (i=0; i<2*nproc; i++) {
106  ptr_snddat[i]=-1.;
107  ptr_rcvdat[i]=0.;
108  }
109  for (i=0; i<nproc; i++)
110  {
111  ptr_snddat[2*i]=(irank+1)*10000+(i+1);
112  ptr_sndmap[i]=2*i; // taking only every second
113  ptr_rcvmap[i]=2*(nproc-1-i); // inverts order and puts to every second
114  for (k=0; k<nproc; k++) ptr_rcvdat[2*(nproc-1-i)]+=(k+1)*10000+(i+1);
115  }
116  for (i=0; i<2*nproc; i++) { ptr_snddat2[2*i+0]=ptr_snddat[i]; ptr_snddat2[2*i+1]=ptr_snddat[i]+1; }
117  for (i=0; i<2*nproc; i++) { ptr_rcvdat2[2*i+0]=ptr_rcvdat[i]; ptr_rcvdat2[2*i+1]=ptr_rcvdat[i]+(double)nproc; }
118  sndcnt=nproc;
119  vec_snddat.assign(ptr_snddat,ptr_snddat+2*nproc);
120  vec_rcvdat.assign(ptr_rcvdat,ptr_rcvdat+2*nproc);
121  vec_sndmap.assign(ptr_sndmap,ptr_sndmap+nproc);
122  vec_rcvmap.assign(ptr_rcvmap,ptr_rcvmap+nproc);
123  vec_snddat2.assign(ptr_snddat2,ptr_snddat2+4*nproc);
124  vec_rcvdat2.assign(ptr_rcvdat2,ptr_rcvdat2+4*nproc);
125  }
126 
128  class optest {
129  public:
131  int ival;
132  double dval;
134  void init(){
135  ival=PE::Comm::instance().rank()+1;
136  dval=(double)PE::Comm::instance().rank()+10.;
137  }
139  optest operator +(const optest& b) const { optest t; t.ival=ival+b.ival; t.dval=dval+b.dval; return t; };
141  bool test()
142  {
143  int i;
144  int nproc=PE::Comm::instance().size();
145  int itest=0;
146  for(i=0; i<nproc; i++) itest+=i+1;
147  double dtest=0.;
148  for(i=0; i<nproc; i++) dtest+=(double)i+10.;
149  return ((ival==itest)&&(dval==dtest));
150  }
151  };
152 
153 };
154 
156 
157 BOOST_FIXTURE_TEST_SUITE( PEAllReduceSuite, PEAllReduceFixture )
158 
159 
162 {
163  PEProcessSortedExecute(-1,CFinfo << "Testing all_reduce " << irank << "/" << nproc << CFendl; );
164 }
165 
167 
168 BOOST_AUTO_TEST_CASE( all_reduce_most_common_ops )
169 {
170  int i;
171  int ival,itest,iresult;
172  double dval,dtest,dresult;
173  ival=irank+1;
174  dval=(double)irank+1.;
175 
176  // testing plus
177  itest=0;
178  dtest=0.;
179  for(i=0; i<nproc; i++) { itest+=i+1; dtest+=(double)i+1.; }
180  iresult=-1;
181  dresult=-1.;
182  PE::Comm::instance().all_reduce(PE::plus(), &ival, 1, &iresult);
183  BOOST_CHECK_EQUAL( iresult, itest );
184  PE::Comm::instance().all_reduce(PE::plus(), &dval, 1, &dresult);
185  BOOST_CHECK_EQUAL( dresult, dtest );
186 
187  // testing multiplies
188  itest=1;
189  dtest=1.;
190  for(i=0; i<nproc; i++) { itest*=i+1; dtest*=(double)i+1.; }
191  iresult=-1;
192  dresult=-1.;
193  PE::Comm::instance().all_reduce(PE::multiplies(), &ival, 1, &iresult);
194  BOOST_CHECK_EQUAL( iresult, itest );
195  PE::Comm::instance().all_reduce(PE::multiplies(), &dval, 1, &dresult);
196  BOOST_CHECK_EQUAL( dresult, dtest );
197 
198  // testing max
199  itest=nproc;
200  dtest=(double)nproc;
201  iresult=-1;
202  dresult=-1.;
203  PE::Comm::instance().all_reduce(PE::max(), &ival, 1, &iresult);
204  BOOST_CHECK_EQUAL( iresult, itest );
205  PE::Comm::instance().all_reduce(PE::max(), &dval, 1, &dresult);
206  BOOST_CHECK_EQUAL( dresult, dtest );
207 
208  // testing min
209  itest=1;
210  dtest=1.;
211  iresult=-1;
212  dresult=-1.;
213  PE::Comm::instance().all_reduce(PE::min(), &ival, 1, &iresult);
214  BOOST_CHECK_EQUAL( iresult, itest );
215  PE::Comm::instance().all_reduce(PE::min(), &dval, 1, &dresult);
216  BOOST_CHECK_EQUAL( dresult, dtest );
217 }
218 
220 
221 BOOST_AUTO_TEST_CASE( all_reduce_operator_of_class )
222 {
223  int r;
224  optest in[3],out[3];
225  in[0].init();
226  in[1].init();
227  in[2].init();
228  PE::Comm::instance().all_reduce(PE::plus(), in, 3, out);
229  BOOST_CHECK_EQUAL( out[0].test() , true );
230  BOOST_CHECK_EQUAL( out[1].test() , true );
231  BOOST_CHECK_EQUAL( out[2].test() , true );
232 }
233 
235 
236 BOOST_AUTO_TEST_CASE( all_reduce_ptr_constant )
237 {
238  int i;
239 
240  setup_data_constant();
241 
242  delete[] ptr_tmprcv;
243  ptr_tmprcv=0;
244 
245  ptr_tmprcv=PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat, sndcnt, (double*)0);
246  for (i=0; i<2*nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv[i] , ptr_rcvdat[i] );
247 
248  for (i=0; i<2*nproc; i++) ptr_tmprcv[i]=0.;
249  PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat, sndcnt, ptr_tmprcv);
250  for (i=0; i<2*nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv[i] , ptr_rcvdat[i] );
251 
252  for (i=0; i<2*nproc; i++) ptr_tmprcv[i]=ptr_snddat[i];
253  PE::Comm::instance().all_reduce(PE::plus(), ptr_tmprcv, sndcnt, ptr_tmprcv);
254  for (i=0; i<2*nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv[i] , ptr_rcvdat[i] );
255 
256  delete[] ptr_tmprcv2;
257  ptr_tmprcv2=0;
258 
259  ptr_tmprcv2=PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat2, sndcnt, (double*)0, 2);
260  for (i=0; i<4*nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[i] , ptr_rcvdat2[i] );
261 
262  for (i=0; i<4*nproc; i++) ptr_tmprcv2[i]=0.;
263  PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat2, sndcnt, ptr_tmprcv2, 2);
264  for (i=0; i<4*nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[i] , ptr_rcvdat2[i] );
265 
266  for (i=0; i<4*nproc; i++) ptr_tmprcv2[i]=ptr_snddat2[i];
267  PE::Comm::instance().all_reduce(PE::plus(), ptr_tmprcv2, sndcnt, ptr_tmprcv2, 2);
268  for (i=0; i<4*nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[i] , ptr_rcvdat2[i] );
269 
270 }
271 
273 
274 BOOST_AUTO_TEST_CASE( all_reduce_vector_constant )
275 {
276  int i;
277 
278  setup_data_constant();
279 
280  vec_tmprcv.resize(0);
281  vec_tmprcv.reserve(0);
282  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat, vec_tmprcv);
283  for (i=0; i<2*nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv[i] , vec_rcvdat[i] );
284  BOOST_CHECK_EQUAL( (int)vec_tmprcv.size() , sndcnt );
285 
286  vec_tmprcv.assign(2*nproc,0.);
287  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat, vec_tmprcv);
288  for (i=0; i<2*nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv[i] , vec_rcvdat[i] );
289 
290  vec_tmprcv=vec_snddat;
291  PE::Comm::instance().all_reduce(PE::plus(), vec_tmprcv, vec_tmprcv);
292  for (i=0; i<2*nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv[i] , vec_rcvdat[i] );
293 
294  vec_tmprcv2.resize(0);
295  vec_tmprcv2.reserve(0);
296  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat2, vec_tmprcv2, 2);
297  for (i=0; i<4*nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[i] , vec_rcvdat2[i] );
298  BOOST_CHECK_EQUAL( (int)vec_tmprcv2.size() , 2*sndcnt );
299 
300  vec_tmprcv2.assign(4*nproc,0.);
301  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat2, vec_tmprcv2, 2);
302  for (i=0; i<4*nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[i] , vec_rcvdat2[i] );
303 
304  vec_tmprcv2=vec_snddat2;
305  PE::Comm::instance().all_reduce(PE::plus(), vec_tmprcv2, vec_tmprcv2, 2);
306  for (i=0; i<4*nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[i] , vec_rcvdat2[i] );
307 }
308 
310 
311 BOOST_AUTO_TEST_CASE( all_reduce_ptr_variable )
312 {
313  int i;
314 
315  setup_data_variable();
316 
317  delete[] ptr_tmprcv;
318  ptr_tmprcv=0;
319  ptr_tmprcv=PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat, sndcnt, ptr_sndmap, (double*)0, ptr_rcvmap);
320  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv[2*i] , ptr_rcvdat[2*i] );
321 
322  delete[] ptr_tmprcv;
323  ptr_tmprcv=new double[2*nproc];
324  for (i=0; i<2*nproc; i++) ptr_tmprcv[i]=0.;
325  PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat, sndcnt, ptr_sndmap, ptr_tmprcv, ptr_rcvmap);
326  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv[2*i] , ptr_rcvdat[2*i] );
327 
328  for (i=0; i<2*nproc; i++) ptr_tmprcv[i]=ptr_snddat[i];
329  PE::Comm::instance().all_reduce(PE::plus(), ptr_tmprcv, sndcnt, ptr_sndmap, ptr_tmprcv, ptr_rcvmap);
330  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv[2*i] , ptr_rcvdat[2*i] );
331 
332  delete[] ptr_tmprcv2;
333  ptr_tmprcv2=0;
334  ptr_tmprcv2=PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat2, sndcnt, ptr_sndmap, (double*)0, ptr_rcvmap, 2);
335  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[4*i+0] , ptr_rcvdat2[4*i+0] );
336  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[4*i+1] , ptr_rcvdat2[4*i+1] );
337 
338  delete[] ptr_tmprcv2;
339  ptr_tmprcv2=new double[4*nproc];
340  for (i=0; i<4*nproc; i++) ptr_tmprcv2[i]=0.;
341  PE::Comm::instance().all_reduce(PE::plus(), ptr_snddat2, sndcnt, ptr_sndmap, ptr_tmprcv2, ptr_rcvmap, 2);
342  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[4*i+0] , ptr_rcvdat2[4*i+0] );
343  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[4*i+1] , ptr_rcvdat2[4*i+1] );
344 
345  for (i=0; i<4*nproc; i++) ptr_tmprcv2[i]=ptr_snddat2[i];
346  PE::Comm::instance().all_reduce(PE::plus(), ptr_tmprcv2, sndcnt, ptr_sndmap, ptr_tmprcv2, ptr_rcvmap, 2);
347  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[4*i+0] , ptr_rcvdat2[4*i+0] );
348  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( ptr_tmprcv2[4*i+1] , ptr_rcvdat2[4*i+1] );
349 }
350 
352 
353 BOOST_AUTO_TEST_CASE( all_reduce_vector_variable )
354 {
355  int i;
356 
357  setup_data_variable();
358 
359  vec_tmprcv.resize(0);
360  vec_tmprcv.reserve(0);
361  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat, vec_sndmap, vec_tmprcv, vec_rcvmap);
362  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv[2*i] , vec_rcvdat[2*i] );
363 
364  vec_tmprcv.resize(2*nproc);
365  vec_tmprcv.reserve(2*nproc);
366  for (i=0; i<2*nproc; i++) vec_tmprcv[i]=0.;
367  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat, vec_sndmap, vec_tmprcv, vec_rcvmap);
368  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv[2*i] , vec_rcvdat[2*i] );
369 
370  vec_tmprcv=vec_snddat;
371  PE::Comm::instance().all_reduce(PE::plus(), vec_tmprcv, vec_sndmap, vec_tmprcv, vec_rcvmap);
372  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv[2*i] , vec_rcvdat[2*i] );
373 
374  vec_tmprcv2.resize(0);
375  vec_tmprcv2.reserve(0);
376  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat2, vec_sndmap, vec_tmprcv2, vec_rcvmap, 2);
377  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[4*i+0] , vec_rcvdat2[4*i+0] );
378  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[4*i+1] , vec_rcvdat2[4*i+1] );
379 
380  vec_tmprcv2.resize(4*nproc);
381  vec_tmprcv2.reserve(4*nproc);
382  vec_tmprcv2.assign(4*nproc,0.);
383  PE::Comm::instance().all_reduce(PE::plus(), vec_snddat2, vec_sndmap, vec_tmprcv2, vec_rcvmap, 2);
384  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[4*i+0] , vec_rcvdat2[4*i+0] );
385  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[4*i+1] , vec_rcvdat2[4*i+1] );
386 
387  vec_tmprcv2=vec_snddat2;
388  PE::Comm::instance().all_reduce(PE::plus(), vec_tmprcv2, vec_sndmap, vec_tmprcv2, vec_rcvmap, 2);
389  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[4*i+0] , vec_rcvdat2[4*i+0] );
390  for (i=0; i<nproc; i++) BOOST_CHECK_EQUAL( vec_tmprcv2[4*i+1] , vec_rcvdat2[4*i+1] );
391 }
392 
394 
395 BOOST_AUTO_TEST_SUITE_END()
396 
397 
#define CFinfo
these are always defined
Definition: Log.hpp:104
void setup_data_constant()
helper function for constant size data - setting up input and verification data
~PEAllReduceFixture()
common tear-down for each test case
#define CFendl
Definition: Log.hpp:109
Real max(const Real a, const Real b)
Maximum between two scalars.
Definition: Terminals.hpp:228
void setup_data_variable()
helper function for variable size data - setting up input and verification data
std::vector< double > vec_snddat
data for std::vectors
Real min(const Real a, const Real b)
Minimum between two scalars.
Definition: Terminals.hpp:234
PEAllReduceFixture()
common setup for each test case
T * all_reduce(const Communicator &comm, const Op &op, const T *in_values, const int in_n, T *out_values, const int stride=1)
Definition: all_reduce.hpp:117
test class with operator + to test if operations and all_reduce can work with it
optest operator+(const optest &b) const
operator +
BOOST_AUTO_TEST_CASE(all_reduce)
#define PEProcessSortedExecute(irank, expression)
Definition: debug.hpp:43
Send comments to:
COOLFluiD Web Admin