COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-parallel-operations.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 checking operations handling."
13 
15 
16 #include <boost/test/unit_test.hpp>
17 
18 #include "common/Log.hpp"
19 #include "common/PE/Comm.hpp"
20 #include "common/PE/operations.hpp"
21 
22 #include "common/PE/debug.hpp"
23 
25 
26 using namespace cf3;
27 using namespace cf3::common;
28 
30 
32 {
35  {
36  m_argc = boost::unit_test::framework::master_test_suite().argc;
37  m_argv = boost::unit_test::framework::master_test_suite().argv;
38  }
39 
42 
44  int m_argc;
45  char** m_argv;
46 
48  class custommult {
49  public:
50 
52  static const bool is_commutative=true;
53 
55  template<typename T> static void func(void* in, void* out, int* len, PE::Datatype* type){
56  int rank,i;
57  T *in_=(T*)in;
58  T *out_=(T*)out;
59  for (i=0; i<*len; i++) out_[i]= out_[i]*in_[i];
60  }
61  };
62 
64  template<typename T, typename Op> PE::Operation mimic_usage( T& t, Op ) { return PE::get_mpi_op<T, Op>::op(); };
65 
67  class optest {
68  public:
69  int ival;
70  double dval;
71  // note that these operators are bogus
72  optest operator + (const optest& b) const { optest t; t.ival=-1; t.dval=-1.; return t; };
73  optest operator * (const optest& b) const { optest t; t.ival=-1; t.dval=-1.; return t; };
74  bool operator > (const optest& b) const { return true; };
75  bool operator < (const optest& b) const { return true; };
76  optest operator &&(const optest& b) const { optest t; t.ival=-1; t.dval=-1.; return t; };
77  optest operator ||(const optest& b) const { optest t; t.ival=-1; t.dval=-1.; return t; };
78  optest operator ! () const { optest t; t.ival=-1; t.dval=-1.; return t; };
79  optest operator & (const optest& b) const { optest t; t.ival=-1; t.dval=-1.; return t; };
80  optest operator | (const optest& b) const { optest t; t.ival=-1; t.dval=-1.; return t; };
81  optest operator ^ (const optest& b) const { optest t; t.ival=-1; t.dval=-1.; return t; };
82  };
83 
85  template <typename T> void test_all_operations(){
86  T t;
87  BOOST_CHECK_EQUAL( mimic_usage(t,PE::max()), MPI_MAX);
88  BOOST_CHECK_EQUAL( mimic_usage(t,PE::min()), MPI_MIN);
89  BOOST_CHECK_EQUAL( mimic_usage(t,PE::plus()), MPI_SUM);
90  BOOST_CHECK_EQUAL( mimic_usage(t,PE::multiplies()), MPI_PROD);
91  BOOST_CHECK_EQUAL( mimic_usage(t,PE::logical_and()), MPI_LAND);
92  BOOST_CHECK_EQUAL( mimic_usage(t,PE::logical_or()), MPI_LOR);
93  BOOST_CHECK_EQUAL( mimic_usage(t,PE::logical_xor()), MPI_LXOR);
94  BOOST_CHECK_EQUAL( mimic_usage(t,PE::bitwise_and()), MPI_BAND);
95  BOOST_CHECK_EQUAL( mimic_usage(t,PE::bitwise_or()), MPI_BOR);
96  BOOST_CHECK_EQUAL( mimic_usage(t,PE::bitwise_xor()), MPI_BXOR);
97  }
98 
99 };
100 
102 
110 
112 
113 BOOST_FIXTURE_TEST_SUITE( PEOperationsSuite, PEOperationsFixture )
114 
115 
118 {
119  PE::Comm::instance().init(m_argc,m_argv);
120  BOOST_CHECK_EQUAL( PE::Comm::instance().is_active() , true );
121  PEProcessSortedExecute(-1,CFinfo << "Proccess " << PE::Comm::instance().rank() << "/" << PE::Comm::instance().size() << " reports in." << CFendl;);
122 }
123 
125 
126 BOOST_AUTO_TEST_CASE( operations_built_in_types )
127 {
128  // each called two times to check re-registration
129  test_all_operations<char>();
130  test_all_operations<char>();
131  test_all_operations<unsigned char>();
132  test_all_operations<unsigned char>();
133  test_all_operations<short>();
134  test_all_operations<short>();
135  test_all_operations<unsigned short>();
136  test_all_operations<unsigned short>();
137  test_all_operations<int>();
138  test_all_operations<int>();
139  test_all_operations<unsigned int>();
140  test_all_operations<unsigned int>();
141  test_all_operations<long>();
142  test_all_operations<long>();
143  test_all_operations<unsigned long>();
144  test_all_operations<unsigned long>();
145  test_all_operations<long long>();
146  test_all_operations<long long>();
147  test_all_operations<unsigned long long>();
148  test_all_operations<unsigned long long>();
149  test_all_operations<float>();
150  test_all_operations<float>();
151  test_all_operations<double>();
152  test_all_operations<double>();
153  test_all_operations<long double>();
154  test_all_operations<long double>();
155 }
156 
158 
159 BOOST_AUTO_TEST_CASE( operations_registered_types )
160 {
161  int i;
162  double d;
163  optest o;
164 
165  // check if registering goes fine
166  mpi_op_customplus_i=mimic_usage(i,PE::customplus());
167  BOOST_CHECK_NE(mpi_op_customplus_i,(PE::Operation)nullptr);
168  mpi_op_customplus_d=mimic_usage(d,PE::customplus());
169  BOOST_CHECK_NE(mpi_op_customplus_d,(PE::Operation)nullptr);
170  mpi_op_customplus_o=mimic_usage(o,PE::customplus());
171  BOOST_CHECK_NE(mpi_op_customplus_o,(PE::Operation)nullptr);
172  mpi_op_custommult_i=mimic_usage(i, custommult());
173  BOOST_CHECK_NE(mpi_op_custommult_i,(PE::Operation)nullptr);
174  mpi_op_custommult_d=mimic_usage(d, custommult());
175  BOOST_CHECK_NE(mpi_op_custommult_d,(PE::Operation)nullptr);
176  mpi_op_custommult_o=mimic_usage(o, custommult());
177  BOOST_CHECK_NE(mpi_op_custommult_o,(PE::Operation)nullptr);
178 
179  // check if no glitch and separate types go to separate static variables
193 
194  // check if re-registration does not alter the MPI_operations (avoid committing the same type over and over)
195  BOOST_CHECK_EQUAL(mpi_op_customplus_i,mimic_usage(i,PE::customplus()));
196  BOOST_CHECK_EQUAL(mpi_op_customplus_d,mimic_usage(d,PE::customplus()));
197  BOOST_CHECK_EQUAL(mpi_op_customplus_o,mimic_usage(o,PE::customplus()));
198  BOOST_CHECK_EQUAL(mpi_op_custommult_i,mimic_usage(i, custommult()));
199  BOOST_CHECK_EQUAL(mpi_op_custommult_d,mimic_usage(d, custommult()));
200  BOOST_CHECK_EQUAL(mpi_op_custommult_o,mimic_usage(o, custommult()));
201 }
202 
204 
205 BOOST_AUTO_TEST_CASE( operations_registered_types_are_really_static )
206 {
207  int i;
208  double d;
209  optest o;
210 
211  // check if re-registration does not alter the MPI_operations (avoid committing the same type over and over)
212  BOOST_CHECK_EQUAL(mpi_op_customplus_i,mimic_usage(i,PE::customplus()));
213  BOOST_CHECK_EQUAL(mpi_op_customplus_d,mimic_usage(d,PE::customplus()));
214  BOOST_CHECK_EQUAL(mpi_op_customplus_o,mimic_usage(o,PE::customplus()));
215  BOOST_CHECK_EQUAL(mpi_op_custommult_i,mimic_usage(i, custommult()));
216  BOOST_CHECK_EQUAL(mpi_op_custommult_d,mimic_usage(d, custommult()));
217  BOOST_CHECK_EQUAL(mpi_op_custommult_o,mimic_usage(o, custommult()));
218 }
219 
221 
222 BOOST_AUTO_TEST_CASE( built_in_operation_with_custom_datatype )
223 {
224  optest o;
225  // check if non built-in datatype does not fall back to built-in Operation
226  BOOST_CHECK_NE( mimic_usage(o,PE::max()), MPI_MAX);
227  BOOST_CHECK_NE( mimic_usage(o,PE::min()), MPI_MIN);
228  BOOST_CHECK_NE( mimic_usage(o,PE::plus()), MPI_SUM);
229  BOOST_CHECK_NE( mimic_usage(o,PE::multiplies()), MPI_PROD);
230  BOOST_CHECK_NE( mimic_usage(o,PE::logical_and()), MPI_LAND);
231  BOOST_CHECK_NE( mimic_usage(o,PE::logical_or()), MPI_LOR);
232  BOOST_CHECK_NE( mimic_usage(o,PE::logical_xor()), MPI_LXOR);
233  BOOST_CHECK_NE( mimic_usage(o,PE::bitwise_and()), MPI_BAND);
234  BOOST_CHECK_NE( mimic_usage(o,PE::bitwise_or()), MPI_BOR);
235  BOOST_CHECK_NE( mimic_usage(o,PE::bitwise_xor()), MPI_BXOR);
236 }
237 
239 
241 {
242  PEProcessSortedExecute(-1,CFinfo << "Proccess " << PE::Comm::instance().rank() << "/" << PE::Comm::instance().size() << " says good bye." << CFendl;);
244  BOOST_CHECK_EQUAL( PE::Comm::instance().is_active() , false );
245 }
246 
248 
249 BOOST_AUTO_TEST_SUITE_END()
250 
251 
253 
254 
#define CFinfo
these are always defined
Definition: Log.hpp:104
~PEOperationsFixture()
common tear-down for each test case
custom class for checking the non built-in way
static Operation op()
Definition: operations.hpp:65
PE::Operation mpi_op_customplus_i
data stays in scope for checking if registration is really static
void test_all_operations()
helper function for testing all operations on a type
MPI_Datatype Datatype
datatype
Definition: types.hpp:47
PE::Operation mpi_op_customplus_d
PE::Operation mpi_op_customplus_o
static void func(void *in, void *out, int *len, PE::Datatype *type)
Implementation of the operation. See Operation_create in MPI standard documentation for details...
#define CFendl
Definition: Log.hpp:109
Real max(const Real a, const Real b)
Maximum between two scalars.
Definition: Terminals.hpp:228
PE::Operation mpi_op_custommult_d
Real min(const Real a, const Real b)
Minimum between two scalars.
Definition: Terminals.hpp:234
BOOST_AUTO_TEST_CASE(init)
void init(int argc=0, char **args=0)
Definition: Comm.cpp:80
Top-level namespace for coolfluid.
Definition: Action.cpp:18
PEOperationsFixture()
common setup for each test case
bool operator<(const Handle< T > &a, const Handle< U > &b)
Definition: Handle.hpp:227
PE::Operation mpi_op_custommult_i
PE::Operation mpi_op_custommult_o
static Comm & instance()
Return a reference to the current PE.
Definition: Comm.cpp:44
PE::Operation mimic_usage(T &t, Op)
mimicer function for templatization (basically a substituter for all_reudce)
Most basic kernel library.
Definition: Action.cpp:19
MPI_Op Operation
operation (mostly for reduce and all_reduce)
Definition: types.hpp:44
#define PEProcessSortedExecute(irank, expression)
Definition: debug.hpp:43
Send comments to:
COOLFluiD Web Admin