COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-common-mpi-buffer.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 #define BOOST_TEST_DYN_LINK
8 #define BOOST_TEST_MODULE "Test module for parallel fields"
9 
10 #include <iomanip>
11 #include <boost/test/unit_test.hpp>
12 
13 #include "common/Log.hpp"
14 #include "common/Core.hpp"
15 #include "common/Environment.hpp"
16 
17 #include "common/Foreach.hpp"
18 #include "common/OSystem.hpp"
19 #include "common/OSystemLayer.hpp"
20 
21 #include "common/PE/Comm.hpp"
22 #include "common/PE/Buffer.hpp"
23 #include "common/PE/debug.hpp"
24 
25 using namespace boost;
26 using namespace cf3;
27 using namespace cf3::common;
28 using namespace cf3::common::PE;
29 
31 
33 {
36  {
37  // uncomment if you want to use arguments to the test executable
38  m_argc = boost::unit_test::framework::master_test_suite().argc;
39  m_argv = boost::unit_test::framework::master_test_suite().argv;
40 
41  }
42 
45  {
46  }
47 
49  int m_argc;
50  char** m_argv;
51 };
52 
54 
55 BOOST_FIXTURE_TEST_SUITE( MPIBufferTests_TestSuite, MPIBufferTests_Fixture )
56 
57 
60 {
61  Core::instance().initiate(m_argc,m_argv);
62  PE::Comm::instance().init(m_argc,m_argv);
63 }
64 
66 
67 BOOST_AUTO_TEST_CASE( test_pack_unpack )
68 {
69  PE::Buffer buf;
70  buf << 1u << 2u << 3.0 << 4 << true;
71  BOOST_CHECK_EQUAL( buf.more_to_unpack(), true);
72 
73  Uint data_unsigned;
74  Real data_real;
75  int data_integer;
76  std::vector<Real> data_array_real;
77  std::string data_string;
78  std::vector<std::string> data_array_string;
79  bool data_bool;
80 
81  buf >> data_unsigned; BOOST_CHECK_EQUAL(data_unsigned, 1u );
82  buf >> data_unsigned; BOOST_CHECK_EQUAL(data_unsigned, 2u );
83  buf >> data_real; BOOST_CHECK_EQUAL(data_real, 3.0 );
84  buf >> data_integer; BOOST_CHECK_EQUAL(data_integer, 4 );
85  buf >> data_bool; BOOST_CHECK_EQUAL(data_bool, true);
86  BOOST_CHECK_EQUAL( buf.more_to_unpack(), false);
87 
88 
89  buf << 5; buf >> data_integer; BOOST_CHECK_EQUAL (data_integer , 5);
90  BOOST_CHECK_EQUAL( buf.more_to_unpack(), false);
91 
92  buf << std::vector<Real>(4,6.);
93  buf >> data_array_real;
94 
95  BOOST_CHECK_EQUAL(data_array_real.size(), 4u);
96  BOOST_CHECK_EQUAL(data_array_real[0], 6.);
97  BOOST_CHECK_EQUAL(data_array_real[1], 6.);
98  BOOST_CHECK_EQUAL(data_array_real[2], 6.);
99  BOOST_CHECK_EQUAL(data_array_real[3], 6.);
100  BOOST_CHECK_EQUAL( buf.more_to_unpack(), false);
101 
102  boost::multi_array<Real,2> table;
103  table.resize(boost::extents[4][3]);
104  table[2][0]=1.;
105  table[2][1]=2.;
106  table[2][2]=3.;
107 
108  buf << table[2];
109  buf >> data_array_real;
110  BOOST_CHECK_EQUAL(data_array_real[0], 1.);
111  BOOST_CHECK_EQUAL(data_array_real[1], 2.);
112  BOOST_CHECK_EQUAL(data_array_real[2], 3.);
113  BOOST_CHECK_EQUAL( buf.more_to_unpack(), false);
114 
115  buf << std::string("a nice string");
116  buf >> data_string;
117  BOOST_CHECK_EQUAL(data_string, std::string("a nice string"));
118  BOOST_CHECK_EQUAL(buf.more_to_unpack(), false);
119 
120  buf << std::vector<std::string>(3,"another nice string");
121  buf >> data_array_string;
122  BOOST_CHECK_EQUAL(data_array_string[0], std::string("another nice string"));
123  BOOST_CHECK_EQUAL(data_array_string[1], std::string("another nice string"));
124  BOOST_CHECK_EQUAL(data_array_string[2], std::string("another nice string"));
125  BOOST_CHECK_EQUAL(buf.more_to_unpack(), false);
126 
127 }
128 
130 
131 BOOST_AUTO_TEST_CASE( test_broadcast )
132 {
133 
134  // Initialize some data, different for every processor
135 
136  int first = Comm::instance().rank();
137  Real second = (1+static_cast<Real>(Comm::instance().rank()))*1e-6;
138  bool third = (first == 0);
139  std::string fourth = "from_proc_" + to_str(first);
140  std::vector<int> fifth(3,first);
141 
142 
143  Uint expected_size =
144  sizeof(int) // first
145  + sizeof(Real) // second
146  + sizeof(Uint) // third
147  + sizeof(Uint)+sizeof(char)*fourth.size() // fourth
148  + sizeof(size_t)+sizeof(int)*fifth.size(); // fifth
149 
150  std::cout << "expected size is " << expected_size << std::endl;
151 // Uint expected_size = 51;
152 
153  // ----------------------------------
154 
155  // Create a buffer
156  common::PE::Buffer buffer;
157  int root = 0;
158 
159  // pack the buffer on root processor
160  if (Comm::instance().rank() == root)
161  buffer << first << second << third << fourth << fifth;
162 
163  // broad cast the buffer from root processor
164  buffer.broadcast(root);
165 
166  // unpack the buffer on other processors
167  if (Comm::instance().rank() != root)
168  buffer >> first >> second >> third >> fourth >> fifth;
169 
170  // ----------------------------------
171 
172  BOOST_CHECK_EQUAL(buffer.size(), expected_size);
173 
174  if (Comm::instance().rank() != root)
175  {
176  BOOST_CHECK_EQUAL(buffer.more_to_unpack(), false);
177  }
178 
179  // The data on every processor should be from rank root
180  BOOST_CHECK_EQUAL(first, 0);
181  BOOST_CHECK_EQUAL(second, 1e-6);
182  BOOST_CHECK_EQUAL(third, true);
183  BOOST_CHECK_EQUAL(fourth, "from_proc_0");
184  BOOST_CHECK_EQUAL(fifth[2], 0);
185 }
186 
188 
189 BOOST_AUTO_TEST_CASE( test_all_gather )
190 {
191 
192  // Initialize some data, different for every processor
193 
194  std::string str = "from_proc_" + to_str(Comm::instance().rank());
195 
196  // ----------------------------------
197 
198  // Create a buffer
199  common::PE::Buffer buffer;
200  buffer << str;
201 
202  common::PE::Buffer out_buf;
203  buffer.all_gather(out_buf);
204 
205  while (out_buf.more_to_unpack())
206  {
207  out_buf >> str;
208  CFinfo << str << CFendl;
209  }
210 }
211 
213 
214 BOOST_AUTO_TEST_CASE( finalize_mpi )
215 {
216  Comm::instance().finalize();
217  Core::instance().terminate();
218 }
219 
221 
222 BOOST_AUTO_TEST_SUITE_END()
223 
224 
#define CFinfo
these are always defined
Definition: Log.hpp:104
~MPIBufferTests_Fixture()
common tear-down for each test case
external boost library namespace
tuple root
Definition: coolfluid.py:24
#define CFendl
Definition: Log.hpp:109
Real e()
Definition of the Unit charge [C].
Definition: Consts.hpp:30
void broadcast(const Uint root)
Broadcast the buffer from the root process.
Definition: Buffer.hpp:464
Common_API std::string to_str(const T &v)
Converts to std::string.
BOOST_AUTO_TEST_CASE(init_mpi)
Buffer that can hold multiple data types, useful for MPI communication.
Definition: Buffer.hpp:34
Top-level namespace for coolfluid.
Definition: Action.cpp:18
int m_argc
possibly common functions used on the tests below
bool more_to_unpack() const
Tell if everything is unpacked.
Definition: Buffer.hpp:80
MPIBufferTests_Fixture()
common setup for each test case
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
Classes offering a MPI interface for COOLFluiD.
Definition: all_gather.hpp:39
void all_gather(Buffer &recv)
All Gather collective operation for buffers.
Definition: Buffer.hpp:483
int size() const
Size of valid parts of buffer.
Definition: Buffer.hpp:67
MPI communication buffer for mixed data types.
Most basic kernel library.
Definition: Action.cpp:19
Send comments to:
COOLFluiD Web Admin