COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-parallel-collective-example.cpp
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 // IMPORTANT:
8 // run it both on 1 and many cores
9 // for example: mpirun -np 4 ./test-parallel-environment --report_level=confirm or --report_level=detailed
10 
11 #define BOOST_TEST_DYN_LINK
12 #define BOOST_TEST_MODULE "Test module for cf3::common 's parallel environment - part of testing collective communications."
13 
15 
16 #include <vector>
17 #include <numeric>
18 
19 #include <boost/test/unit_test.hpp>
20 #include <boost/lambda/lambda.hpp>
21 #include <boost/foreach.hpp>
22 #include <boost/thread/thread.hpp>
23 
24 #include "common/Log.hpp"
25 #include "common/PE/Comm.hpp"
26 #include "common/PE/debug.hpp"
27 #include "common/PE/datatype.hpp"
28 #include "common/PE/operations.hpp"
29 #include "common/PE/all_to_all.hpp"
30 #include "common/PE/all_reduce.hpp"
31 #include "common/PE/reduce.hpp"
32 #include "common/PE/scatter.hpp"
33 #include "common/PE/broadcast.hpp"
34 #include "common/PE/gather.hpp"
35 #include "common/PE/all_gather.hpp"
36 
38 
39 using namespace cf3;
40 using namespace cf3::common;
41 
43 
45 {
48  {
49  m_argc = boost::unit_test::framework::master_test_suite().argc;
50  m_argv = boost::unit_test::framework::master_test_suite().argv;
51  }
52 
55 
56 // double dd ( int idx, int rank, int nproc ) { return idx * ( rank + 1. ); }
57  double dd ( int idx, int rank, int nproc ) { return rank * 100 + idx; }
58 
60  int m_argc;
61  char** m_argv;
62 
63 };
64 
66 
67 BOOST_FIXTURE_TEST_SUITE( PECollectiveSuite, PECollectiveFixture )
68 
69 
72 {
73  PE::Comm::instance().init(m_argc,m_argv);
74  BOOST_CHECK_EQUAL( PE::Comm::instance().is_active() , true );
75  CFinfo.setFilterRankZero(false);
76  PEProcessSortedExecute(-1,CFinfo << "Proccess " << PE::Comm::instance().rank() << "/" << PE::Comm::instance().size() << " reports in." << CFendl;);
77 }
78 
80 
82 {
83  // double
84 
85  double sum = 0.;
86  for(Uint i = 0; i < PE::Comm::instance().size(); ++i)
87  sum += (double) i ;
88 
89  double rk_result;
90  double rk = PE::Comm::instance().rank();
91  int rk_size = 1;
92 
93  PE::Comm::instance().all_reduce( PE::plus(), &rk, rk_size, &rk_result );
94 
95  BOOST_CHECK_EQUAL( rk_result, sum );
96 
97  // for vectors
98 
99  std::vector<double> v (2);
100  v[0] = PE::Comm::instance().rank();
101  v[1] = PE::Comm::instance().size();
102 
104 #if 0
105  PE::Comm::instance().all_reduce( Comm::max(), &v, v.size(), &v );
106 #endif
107 
108  // this works
109  PE::Comm::instance().all_reduce( PE::plus(), v, v );
110 
111  // this is equivalent
112 // PE::Comm::instance().all_reduce( Comm::plus(), &v[0], v.size(), &v[0] );
113 
114  BOOST_CHECK_EQUAL( v[0], sum );
115  BOOST_CHECK_EQUAL( v[1], PE::Comm::instance().size() * PE::Comm::instance().size() );
116 }
117 
119 
120 BOOST_FIXTURE_TEST_CASE( all_to_all_ring_topology, PECollectiveFixture )
121 {
122  int nproc = PE::Comm::instance().size();
123  int irank = PE::Comm::instance().rank();
124 
125  // neighbour to right
126  int rkright = (irank + 1) % nproc;
127  // neighbour to left
128  int rkleft = (nproc+irank-1) % nproc;
129 
130 // std::cout << "rk left [" << irank << "]" << rkleft << std::endl;
131 // std::cout << "rk right [" << irank << "]" << rkright << std::endl;
132 
133  // data vector
134 
135  std::vector<double> v (100);
136  for(Uint i = 0; i < v.size(); ++i)
137  v[i] = dd(i,irank,nproc);
138 
139  // mapping vectors
140 
141  std::vector<int> send_map (10); // send last 10 entries of data vector
142  for(Uint i = 0; i < send_map.size(); ++i)
143  send_map[i] = 90 + i;
144 
145  std::vector<int> send_num (nproc, 0); // nb of entries to send to each rank (assumes send_map consecutive ordering for each rank )
146  send_num[rkright] = 10;
147 
148  BOOST_CHECK_EQUAL( std::accumulate( send_num.begin(), send_num.end(), 0), send_map.size() );
149 
150  std::vector<int> recv_map (10); // receive 1st 10 entries of data vector
151  for(Uint i = 0; i < recv_map.size(); ++i)
152  recv_map[i] = i;
153 
154  std::vector<int> recv_num (nproc, 0); // nb of entries to receive from each rank (assumes recv_map consecutive ordering for each rank )
155  recv_num[rkleft] = 10;
156 
157  BOOST_CHECK_EQUAL( std::accumulate( recv_num.begin(), recv_num.end(), 0), recv_map.size() );
158 
159  // communications
160 
161  PE::Comm::instance().all_to_all( v, send_num, send_map, v, recv_num, recv_map);
162 
163 // PEDebugVector(v,v.size()); // this prints debug info on a vector !!!
164 
165  // check received data
166  for(Uint i = 0; i < 10; ++i)
167  BOOST_CHECK_EQUAL( v[i], dd(i+90,rkleft,nproc) );
168 
169  // check un-changed data and sent data
170  for(Uint i = 10; i < v.size(); ++i)
171  BOOST_CHECK_EQUAL( v[i], dd(i,irank,nproc) );
172 
173 }
174 
176 
178 {
179  PEProcessSortedExecute(-1,CFinfo << "Proccess " << PE::Comm::instance().rank() << "/" << PE::Comm::instance().size() << " says good bye." << CFendl;);
180  CFinfo.setFilterRankZero(true);
182  BOOST_CHECK_EQUAL( PE::Comm::instance().is_active() , false );
183 }
184 
186 
187 BOOST_AUTO_TEST_SUITE_END()
188 
189 
T * all_reduce(const Op &op, const T *in_values, const int in_n, T *out_values, const int stride=1)
Definition: Comm.hpp:282
#define CFinfo
these are always defined
Definition: Log.hpp:104
double dd(int idx, int rank, int nproc)
#define CFendl
Definition: Log.hpp:109
Uint rank() const
Return rank, additionally, if is_init==0.
Definition: Comm.cpp:135
Real max(const Real a, const Real b)
Maximum between two scalars.
Definition: Terminals.hpp:228
BOOST_FIXTURE_TEST_CASE(init, PECollectiveFixture)
Uint size() const
Return the number of processes, or 1 if is_init==0.
Definition: Comm.cpp:145
void init(int argc=0, char **args=0)
Definition: Comm.cpp:80
Top-level namespace for coolfluid.
Definition: Action.cpp:18
~PECollectiveFixture()
common tear-down 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
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
T * all_to_all(const T *in_values, const int in_n, T *out_values, const int stride=1)
Definition: Comm.hpp:128
static Comm & instance()
Return a reference to the current PE.
Definition: Comm.cpp:44
PECollectiveFixture()
common setup for each test case
Most basic kernel library.
Definition: Action.cpp:19
#define PEProcessSortedExecute(irank, expression)
Definition: debug.hpp:43
Send comments to:
COOLFluiD Web Admin